2013-08-01 11 views
11

Potrzebuję zeskanować listę w Pythonie. Jestem w stanie załadować go z pliku i wykonać prostą operację, ale starałem się wykonać następujące czynności:Skanowanie listy

L = [1,2,3,4,5,6,7,8] 

Począwszy od pierwszego elementu Chcę następujący wynik:

1 
    2,3,4,5,6,7,8 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
2 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
3 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
4 
    5,6,7,8 
    6,7,8 
    7,8 
    8 

i tak dalej.

Próbowałem coś takiego:

fo = open(sys.argv[1], 'r') 
L = fo.readlines() 
for i in range(len(L)): 
    print str(L[i]) 
    for j in range(len(L)-1-i): 
     print '...' + str(L[i+j+1]) 

mógłbyś mi pomóc?

+0

Jestem zdezorientowany ... Drukujesz listę zaczynając od 1,3,4,5,6,7 i 8, a następnie zaczynając od 2, 4, 5, 6, 7, 8, a następnie 3, 5, 7 ... Nie widzę tego wzorca, czy możesz to wyrazić? – Jblasco

+0

Chciałbym tylko dodać, że lepiej byłoby zrobić 'with open (sys.argv [1]," r ") jak dla: # robić rzeczy z fo' ponieważ w ten sposób plik jest automatycznie zamykany, nawet jeśli Wystąpił błąd podczas pracy z nim. Tylko dobra praktyka. – rlms

Odpowiedz

13

Jak to jest? Ładny i prosty do odczytania:

>>> for i, j in enumerate(L): 
...  print L[i] 
...  temp = map(str, L[j:]) 
...  while temp: 
...    print ' ', ','.join(temp) 
...    temp = temp[1:] 
... 
1 
    2,3,4,5,6,7,8 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
2 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
3 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
... 

while temp oznacza natomiast lista temp nie jest pusta. Musimy zadzwonić map(str, L[j:]) tutaj, ponieważ lista jest pełna liczb całkowitych (a więc metoda str.join nie będzie działać)


Kolejna uwaga, to bardziej pythonic do używania with oświadczenie podczas pracy z plikami:

with open(sys.argv[1], 'r') as fo: 
    L = fo.readlines() 
+0

Bardzo ładne, ale czy tego chce użytkownik? Zobacz mój komentarz powyżej. – Jblasco

+2

@Jblasco Wydaje się być identyczne z wyjściem podanym w pytaniu – TerryA

+0

Teraz masz rację. Został zredagowany pomiędzy. – Jblasco

4

Podczas gdy odpowiedź Haidro daje pożądany wynik, powinienem powiedzieć, że jest to dość nieefektywny algorytm do wykonania zadania.

Szybka analiza:

for i, j in enumerate(L):   # loop number 1, for i from 1 to N 
    print L[i] 
    temp = map(str, L[j:])   
    while temp:     # nested loop number 2, for j from i to N 
     print ' ', ','.join(temp) # nested loop number 3, for k from j to N 
     temp = temp[1:] 

to zbyt dużo pracy dla takiego prostego zadania. Myślę, że może być znacznie prostszy i szybszy, łączenie ciągu tylko raz, a następnie drukowanie podłańcuchów (jak DCM wspomniany w komentarzach, aby móc drukować dowolne liczby, należy wstępnie obliczyć pozycje elementów w łańcuchu):

s = ",".join(map(str, l))     # creating string 
p = [len(str(x)) + 1 for x in l]   # calculating length of each element 
p = [sum(p[:i]) for i in range(len(p))] # calculating positions with rolling total 
for i in range(len(l)):     # loop number 1 
    print l[i] 
    for j in range(i + 1, len(l)):   # nested loop number 2 
     print ' ', s[p[j]:] 

Oto krótki profil czasów wykonania (utworzyłem funkcję worker1 z kodem Haidro i worker2 wraz z kopią). Można zobaczyć, jak rośnie czas realizacji przy wzroście długości wejście N:

>>> from timeit import timeit 

>>> timeit("worker1(l)", "from testSO import worker1, l", number=10) 
0.0016222212978796024 
>>> timeit("worker1(l*10)", "from testSO import worker1, l", number=10) 
0.33153371422580324 
>>> timeit("worker1(l*100)", "from testSO import worker1, l", number=10) 
163.25908817145972 

Rośnie jak O(N^3)

>>> timeit("worker2(l)", "from testSO import worker2, l", number=10) 
0.0006974355000011201 
>>> timeit("worker2(l*10)", "from testSO import worker2, l", number=10) 
0.03448374103493279 
>>> timeit("worker2(l*100)", "from testSO import worker2, l", number=10) 
4.446190059150922 

Ten rośnie jak O(N^2)

To nie tak, że myślę, że oryginał pytanie wygląda jak krytyczne zadanie, ale myślę, że byłoby miło, gdyby ludzie zobaczyli, dlaczego dostarczony algorytm może być wolniejszy, niż się spodziewali.

+1

To ma lepszą wydajność, ale jest znacznie mniej solidne, jak napisane. Jeśli długość liczb nie zawsze wynosi 1, nie daje oczekiwanych wyników. – DSM

+0

@DSM, bardzo dobry punkt, ominęło to, sprawdzę to –

+0

@DSM zmienił odpowiedź z wstępnie skomponowanymi pozycjami elementów –

Powiązane problemy