Краткий ответ
Вот пример того, как вы можете улучшить свой код с помощью итераторов:
// WITHOUT ITERATORS
hours_worked = 0
for event in events:
if event.is_billable():
hours_worked += event.duration
// WITH ITERATORS
// create an iterators with the duration of the billable event.
billable_times = (event.duration for event in events if event.is_billable())
hours_worked = sum(billable_times)
С помощью итераторов мы назвали то, что не было названо раньше, и теперь мы можем использовать функцию суммы. Именование делает наш код более наглядным и читаемым.
Подробнее здесь: Python Основы: итерация, итерации, итераторы и циклы
Long Ответ
Python не имеет таких же for
циклов, как другие языки программирования. Вы, наверное, знаете, что в JavaScript "for
l oop" написано так:
let myList = ["apple", "banana", "blueberry"];
for (let i = 0; i < myList.length; i += 1) {
print(myList[i])
}
И, как вы знаете, это Python "for
l oop ":
myList = [1, 2, 3, 5, 7]
for n in myList:
print(n)
Как видите, в Python нет инициализации, увеличения и проверки индекса. В Python, myList
называется итерабельным это все, что вы можете oop с помощью для l oop.
Последовательности являются одним тип итерируемого, но с дополнительными функциями, такими как индексирование, длина и их можно разрезать. Например: строки, кортежи и списки - это итерации и последовательности, а словари - просто итерации. (Вы не можете сделать это со словарем myDict[1]
). В Python мы не можем вручную l oop перебирать каждую итерацию с помощью индексов, это работает только с последовательностями.
Итак, как работают Python «for
циклы», если они могут использовать индексы? Они используют возможности Итераторов . Итераторы - это то, что поддерживает итераторы, вы можете получить по одному из каждой итерации, это то, что вы делаете, когда в вашем коде iter(a)
.
Итераторы можно рассматривать как дозаторы Pez, которые не могут быть перезагружен. Вы можете вынуть Pez, но после того, как Pez удален, он не может быть возвращен, а когда дозатор пуст, он бесполезен.
Источник: L oop лучше: Более глубокий взгляд на итерацию в Python: Статья
Итак, под капотом, в Python, a for l oop работает примерно так:
def for(iterable, action)
iterator = iter(iterable)
looping_finished = false
while not looping_finished:
try:
item = next(iterator)
except StopIteration:
looping_finished = true
else:
action(item)
Но почему нам нужны итераторы? Потому что в Python обычно работают с итератором напрямую.
Вот базовый c пример Python генератора
my+1Generator (n+1 for n in numbers)
Генераторы являются итераторами, это означает, что вы можете сделать это: next(my+1Generator)
и вы также можете l oop над генераторами, например:
for n in my+1Generator:
print(n)
Если вы можете l oop над ним, это итерация. Итак, генераторы - это итераторы, но также итераторы.
И, что удивительно, это то же самое для всех итераторов. Вы действительно можете сделать это:
numbers = [1, 2, 3]
iterator1 = iter(numbers)
iterator2 = iter(iterator1)
print (iterator1 is iterator2) // Output: "True"
Итераторы не имеют длины и не могут быть проиндексированы. Например: enumerate
, reverse
, zip
и map
- итераторы в Python. А самое главное в итераторах - это их лень. Они откладывают свою работу, пока вы не попросите следующий элемент.
Вы можете создать итератор самостоятельно. Вот пример:
class add1_all:
def __init__(self, numbers):
self.numbers = iter(numbers)
def __next__(self):
return next(self.numbers) + 1
def __iter__(self):
return self
но обычно итератор создается с функцией генератора:
def add1_all(numbers):
for n in numbers:
yield n+1
Эти два примера кода эквивалентны и работают одинаково. yield
позволяет нам приостановить выполнение функции add1_all
до тех пор, пока для него не будет вызвана функция next
.
Вот пример того, как вы можете улучшить свой код с помощью итераторов:
// WITHOUT ITERATORS
hours_worked = 0
for event in events:
if event.is_billable():
hours_worked += event.duration
// WITH ITERATORS
// create an iterators with the duration of the billable event.
billable_times = (event.duration for event in events if event.is_billable())
hours_worked = sum(billable_times)
Источники: