Познаваме циклите for и while за итерация. Но знаете ли за функцията next() в Python? next() също може да се използва за итерация през елементи и в тази статия ще изследваме то


# Standard loop

fruits = ['apple', 'orange', 'pear'] 
for fruit in fruits:
    print(fruit)

# apple 
# orange
# pear

Въведение в итераторите


fruits = ['apple', 'orange', 'pear']
iterator = fruits.__iter__()

print(iterator) # 

Ако извикаме метода .__iter__() на някой итеруем обект (списък/речник/и т.н.), получаваме итератор обект. Този итератор обект след това ще се използва с функцията next() за итерация през елементите.


print([1,2,3].__iter__())
print('hello'.__iter__())
print({1:2, 3:4}.__iter__())

Функцията next()


fruits = ['apple', 'orange', 'pear']
iterator = fruits.__iter__()

x = next(iterator)
print(x) # apple

Функцията next(), когато бъде извикана върху итератор обект, ще:

  • върне следващия елемент в итеруемия обект
  • премести указателя на итератора към следващия елемент

fruits = ['apple', 'orange', 'pear'] 
iterator = fruits.__iter__()

print(next(iterator)) # apple
print(next(iterator)) # orange 
print(next(iterator)) # pear

Всеки път, когато извикаме next(iterator), връщаме следващия елемент в итератора.


fruits = ['apple', 'orange', 'pear']
iterator = fruits.__iter__()

print(next(iterator)) # apple
print(next(iterator)) # orange
print(next(iterator)) # pear

print(next(iterator))

# Traceback (most recent call last):
#   File "/Users/sim/Documents/repos/main/a.py", line 8, in 
#     print(next(iterator)) #          
#           ^^^^^^^^^^^^^^
# StopIteration

Когато нашият итератор свърши елементи и опитаме да извикаме next(iterator), ще получим изключение StopIteration.

Итериране през елементи с next()


fruits = ['apple', 'orange', 'pear']
iterator = fruits.__iter__()

while True:
    try:
        x = next(iterator)
        print(x)
    except:
        break

Тъй като изключението StopIteration се появява, когато стигнем до края на итеруемия обект (по същество нашия списък), трябва да използваме блок try-except, за да хванем това изключение и да излезем от цикъла while.

Необходими ли са ни?

Това определено е по-досадно за писане от обикновен цикъл for или while. Но това може да се окаже полезно, ако искаме абсолютен контрол върху процеса на итерация.


def generate_number():
    n = 1
    while True:
        yield n
        n += 1

generator = generate_number()
print(generator)

first = next(generator)
second = next(generator)
third = next(generator)

print(first, second) # 1 2 3

Tова също може да бъде полезно, ако искаме само краен брой елементи от генераторен обект – по този начин не се налага да се справяме с логиката за генериране на първите N елемента и след това да използваме break.

Заключение

Надявам се, че това беше ясно и лесно за разбиране. Използването на next() предлага повече контрол и гъвкавост при итериране през елементи. Въпреки че може да е малко по-досадно от обикновен цикъл, има случаи, в които next() може да бъде полезен инструмент във вашия арсенал от Python.
Експериментирайте с next() и итератор обекти, за да разберете напълно как работят. С времето ще развиете усет кога да ги използвате в своите проекти.

Categorized in:

Работа с данни,

Last Update: май 3, 2024