Чем отличается использование Python lambda внутри и вне функции?

#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