python продолжает цикл с определенного индекса

Я написал код, который использует enumerate для циклического просмотра списка.

for index, item in enumerate(list[start_idx:end_idx])
     print('index [%d] item [%s]'%(str(index), item))

элемент в списке - это просто строки. Иногда я не хочу перечислять весь список, иногда я нарезаю список, делая разные вещи.

Часть, с которой у меня возникают проблемы, - это функция перечисления Python.

Документы говорят, что вы можете сделать:

for index, item in enumerate(list, start_index):
    print(str(index))

приведенный выше код не делает то, что я ожидал. Хотя я перечислил бы начало в начальной позиции и остановился бы в конце, но это не так.

Я написал небольшую программу, и она действительно работает шатко.

>>> for i, x in enumerate(range(0,20),start=4):
...      print(str(i)+'\t'+str(x))
... 
4   0
5   1
6   2
7   3
8   4
9   5
10  6
11  7
12  8
13  9
14  10
15  11
16  12
17  13
18  14
19  15
20  16
21  17
22  18
23  19

Я ожидаю, что перечисление начнется с индекса 4 и зациклится до конца. Таким образом, он получит диапазон от 4 до 19, но кажется, что индекс только начинается, но все еще повторяется от 0 до 19..

Вопрос, есть ли способ сделать итерационный цикл, начинающийся с определенного индекса в python?

Мой ожидаемый результат будет

>>> for i, x in enumerate(range(0,20),start=4):
...      print(str(i)+'\t'+str(x))
... 
4   0 # skip
5   1 # until
6   2 # this
7   3 # item
8   4
9   5
10  6
11  7
12  8
13  9
14  10
15  11
16  12
17  13
18  14
19  15
20  16
21  17
22  18
23  19

вместо запуска индекса в начальной позиции укажите.


person user1610950    schedule 11.10.2016    source источник
comment
Аргумент start, я бы сказал, косметический. Обычно полезно, когда вы хотите начать отсчет с 1 вместо 0 по умолчанию.   -  person Moses Koledoye    schedule 11.10.2016
comment
Между прочим: я чувствую, что то, что вы здесь делаете, немного пахнет кодом. Вам не нужно enumerate, потому что это подразумевает, что вы изменяете элементы списка и возвращаете их на место. Если вы работаете со списком статически, вам вообще не нужно управлять индексами, и вы можете просто перебирать срезы.   -  person kojiro    schedule 11.10.2016


Ответы (3)


На самом деле, если у вас есть объект range, сделать из него срез не составит большого труда, потому что range(n)[:4] по-прежнему является объектом range (как упомянул @MosesKoledoye, это функция Python 3). Но если у вас есть список, чтобы не создавать новый список, вы можете выбрать itertools.islice, он вернет итератор.

from itertools import islice
for index, item in enumerate(islice(range(20), 4, None)):
    print(index, item)

Выход

0 4
1 5
2 6
3 7
4 8
...
person vishes_shell    schedule 11.10.2016
comment
range(n)[:4] по-прежнему является объектом диапазона применимо только к Python 3 - person Moses Koledoye; 11.10.2016
comment
@MosesKoledoye, ты прав, я упомяну об этом в ответ. - person vishes_shell; 11.10.2016
comment
Я немного отредактировал это; для индекса элемент в перечислении (islice (диапазон (20), 4, нет), 4); это заставит бота начинать индекс с 4, а также - person user1610950; 15.10.2016
comment
@user1610950 user1610950 подойдет, рад, что помог тебе! - person vishes_shell; 15.10.2016

Параметр start для enumerate не имеет ничего общего с тем, какие элементы итерации выбираются. Он просто сообщает enumerate, с какого числа начинать.

>>> list(enumerate(range(3)))
[(0, 0), (1, 1), (2, 2)]
>>> list(enumerate(range(3), 1))
[(1, 0), (2, 1), (3, 2)]

Если вы хотите начать с определенного индекса, вам необходимо указать начальный аргумент и срез:

for i, v in enumerate(alist[4:], 4):
    ...
person kojiro    schedule 11.10.2016

Ты можешь сделать:

for index, item in enumerate(list[4:]):
    print(str(index))
person JMat    schedule 11.10.2016
comment
Если вы сделаете это, индексы списка не будут соответствовать выходным данным enumerate. - person kojiro; 11.10.2016
comment
@kojiro, тогда ты можешь сделать for index, item in enumerate(list[4:],4): - person JMat; 11.10.2016