Как я могу ограничить итерации цикла в Python?
скажем, у меня есть список элементов, и я хочу повторить первые несколько из них:
items = list(range(10)) # I mean this to represent any kind of iterable.
limit = 5
наивная реализация
Python naïf, происходящий из других языков, вероятно, напишет этот совершенно исправный и эффективный (если unidiomatic) код:
index = 0
for item in items: # Python's `for` loop is a for-each.
print(item) # or whatever function of that item.
index += 1
if index == limit:
break
более идиоматические реализации
но Python имеет enumerate, который прекрасно объединяет около половины этого кода:
for index, item in enumerate(items):
print(item)
if index == limit: # There's gotta be a better way.
break
таким образом, мы о вырезать дополнительный код в половина. Но должен быть способ получше.
можем ли мы аппроксимировать приведенное ниже поведение псевдокода?
если enumerate взял еще один необязательный
5 ответов
как я могу ограничить итерации цикла в Python?
for index, item in enumerate(items): print(item) if index == limit: break
есть ли более короткий, идиоматический способ написать выше? Как?
включая индекс
zip
останавливается на самой короткой итерации его аргументов. (В отличие от поведения zip_longest
, который использует самую длинную итерацию.)
range
может предоставить ограниченный iterable, который мы можем передать zip вместе с нашим основным повторяемый.
таким образом, мы можем пройти
можно использовать itertools.islice
для этого. Он принимает start
, stop
и step
аргументы, если вы передаете только один аргумент, то он считается как stop
. И он будет работать с любым итерируемым.
itertools.islice(iterable, stop)
itertools.islice(iterable, start, stop[, step])
демо:
>>> from itertools import islice
>>> items = list(range(10))
>>> limit = 5
>>> for item in islice(items, limit):
print item,
...
0 1 2 3 4
пример из docs:
islice('ABCDEFG', 2) --> A B
islice('ABCDEFG', 2, 4) --> C D
islice('ABCDEFG', 2, None) --> C D E F G
islice('ABCDEFG', 0, None, 2) --> A C E G
почему бы просто не использовать
for item in items[:limit]: # or limit+1, depends
print(item) # or whatever function of that item.
Это будет работать только для некоторых итераций, но поскольку вы указали списки, это работает.
Он не работает, если вы используете наборы или дикты и т. д.
Pass islice с пределом внутри перечислить
a = [2,3,4,2,1,4]
for a, v in enumerate(islice(a, 3)):
print(a, v)
выход:
0 2
1 3
2 4
почему бы не цикл до предела или конца списка, в зависимости от того, что происходит раньше, например:
items = range(10)
limit = 5
for i in range(min(limit, len(items))):
print items[i]
выход:
0
1
2
3
4