Сканирование списка
Мне нужно сканировать список в Python. Я могу загрузить его из файла и выполнить простую операцию, но я пытался сделать следующее:
L = [1,2,3,4,5,6,7,8]
Начиная с первого элемента, я хочу создать следующий вывод:
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
и т.д.
Я пытался что-то вроде этого:
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])
Не могли бы вы мне помочь?
Ответы
Ответ 1
Как это? Приятно и легко читать:
>>> 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
означает, что список temp
не пуст. Мы должны называть map(str, L[j:])
здесь, потому что список заполнен целыми числами (и, следовательно, метод str.join
не работает)
Еще одно замечание: более pythonic использовать инструкцию with
при работе с файлами:
with open(sys.argv[1], 'r') as fo:
L = fo.readlines()
Ответ 2
В то время как ответ Haidro дает желаемый результат, я должен сказать, что это довольно неэффективный алгоритм для выполнения поставленной задачи.
быстрый анализ:
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:]
он слишком много работает для такой простой задачи. Я думаю, что это можно сделать намного проще и быстрее, объединив строку только один раз, а затем напечатайте подстроки (как упоминается в комментариях DCM, чтобы иметь возможность печатать произвольные числа, мы должны предварительно вычислять позиции элементов в строке):
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]:]
Здесь быстрый профиль выполнения (я создаю функцию worker1
с кодом Haidro и worker2
с моим). Вы можете видеть, как увеличивается время выполнения при увеличении длины ввода 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
Он растет как 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
Это растет как O(N^2)
Не то, чтобы я думал, что исходный вопрос похож на критическую для производительности задачу, но я думаю, было бы хорошо, если бы люди увидели, почему алгоритм предоставлен, возможно, медленнее, чем они ожидают.