Подтвердить что ты не робот

Сканирование списка

Мне нужно сканировать список в 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])

Не могли бы вы мне помочь?

4b9b3361

Ответ 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)

Не то, чтобы я думал, что исходный вопрос похож на критическую для производительности задачу, но я думаю, было бы хорошо, если бы люди увидели, почему алгоритм предоставлен, возможно, медленнее, чем они ожидают.