#python #lambda
Вопрос:
Сегодня я изучаю Python lambda и написал тестовый пример:
def iterator1(source): print(source) return source def iterator2(source): source1 = lambda : source print(source1) return source1 x = [1,2,3,4,5,6] y = [2,3,4,5,6,7] a = iterator1(lambda: zip(x,y)) b = iterator2(zip(x,y)) for i in range(2): tmp = a() for j in tmp: print(j) print("==============") for i in range(2): print(i) tmp2 = b() for j in tmp2: print(j)
Оба двух итератора возвращают лямбда-функцию.
Разница в том, что я передаю лямбду вне функции в iterator1, но создаю лямбду в iterator2. Я ожидал, что два результата будут одинаковыми, но это не так;
lt;function lt;lambdagt; at 0x7f44da7645e0gt; lt;function iterator2.lt;localsgt;.lt;lambdagt; at 0x7f44da764670gt; (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) ============== 0 (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) 1
Итак, я сбит с толку этим использованием лямбды, это какой-то внутренний механизм, который я не знаю, чтобы иметь дело с функцией лямбды?
Комментарии:
1.
iterator2
возвращает типiterator
и итератор могут быть использованы только один раз, поэтому вы видите такое поведение
Ответ №1:
Ибо a
то, что происходит, должно быть ясно. zip
Итератор создается каждый раз, когда вы это делаете a()
, поэтому у вас есть 2 уникальных итератора, которые нужно просмотреть в цикле for:
for i in range(2): tmp = a() for j in tmp: print(j)
Поскольку b
zip
итератор создается только один раз, здесь:
b = iterator2(zip(x, y))
Вы просто получаете это дважды в цикле:
tmp = b()
Таким образом, при первом запуске цикла for:
for i in range(2): print(i) tmp2 = b() for j in tmp2: print(j)
Zip повторяется снова:
0 (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7)
При следующем вызове b()
возвращается тот же zip
итератор. Но вы только что исчерпали этот итератор в последнем цикле. Таким образом, в итераторе не осталось ничего, что можно было бы просмотреть, в результате чего:
1
Вы можете проверить это, проверив id()
tmp
:
print(id(tmp))
Первый цикл:
2109174712000 # lt;- different IDs (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) 2109174711872 # lt;- different (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) =======
Вторая петля:
0 2109174711936 # lt;- same ID (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) 1 2109174711936 # lt;- same ID