Как работает ключевое слово ʻin` в итераторе?

У меня есть это:

>>> 1 in (i for i in range(0, 5))
True

>>> 2 in (i for i in range(0, 5))
True

после этого:

>>> gen = (i for i in range(0, 5))
>>> 1 in gen
True
>>> 3 in gen
True
>>> 2 in gen
False

Ли ключевое словоin работает как:

3 in gen

равно:

j = 3
for i in gen:
    if i == j:
        return True
    else:
        return False

но после цикла for НЕ СЛЕДУЕТ СБРОСИТЬ Итератор снова.

Это правильно?

3 ответа

Решение

Генераторы поддерживают контекст, когда они дают значение. Итак, когда вы делаете

1 in gen

он начнет повторяться и когда он достигнет 1, это возвращает True, но текущее состояние в 1, Далее, когда вы делаете 3 in genэто повторяется до 3 и дает True, А потом, когда вы делаете

2 in gen

начинается итерация с 3не с самого начала. Вот почему вы получаете False,

В вашей программе

j = 3
for i in gen:
    if i == j:
        return True
    else:
        return False

если i не равно j, он сразу вернется False, Вместо этого это может быть свободно понято как,

return any(i == j for j in gen)

any повторяет генератор, пока какой-либо из элементов не будет соответствовать критериям. Если ни один из предметов не соответствует, он исчерпает генератор и вернется False,

Оператор in работает подобно функции f_in, определенной ниже:

def f_in(aj, gen):
    j = aj
    while(True):
        try:
            if(j == gen.next()):
                return True
        except StopIteration:
            return False
mygen = xrange(5)
agen = iter(mygen)

print f_in(1, agen)
print f_in(3, agen)
print f_in(2, agen)

Это имеет большой смысл, поскольку итератор может быть бесконечным, и для успешного вызова типа 3 в нем не нужно циклически перебирать весь (потенциально бесконечный) итератор.

Из документов по модели данных Python:

Тестирование членства операторов (in а такжеnot in) обычно реализуются как итерация последовательности.

он начинает перебирать итератор, пока не доберется до элемента, и возвращает Trueили исчерпывает итератор и возвращает False, Если итератор не исчерпан, вы все равно можете получить оставшиеся элементы из него, но это не перезапустит генератор, и вы будете перебирать только оставшиеся элементы.

Другие вопросы по тегам