简体   繁体   中英

What's the different of using Python lambda inside and outside a function?

I am studying Python lambda today and I wrote a test case:

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)

Both two iterators return lambda function.

The difference is that I pass the lambda outside the function in iterator1 but construct a lambda in iterator2. I expected the two result are the same, but it doesn't;

<function <lambda> at 0x7f44da7645e0>
<function iterator2.<locals>.<lambda> at 0x7f44da764670>
(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

So I am confused about this usage of lambda, is that some internal mechanism I don't know to deal with lambda function?

For a what's happening should be clear. The zip iterator gets created each time you do a() - so you have 2 unique iterators to go over in your for loop:

for i in range(2):
    tmp = a()
    for j in tmp:
        print(j)

For b , the zip iterator is created only once, here:

b = iterator2(zip(x, y))

You merely fetch that twice in the loop:

tmp = b()

So the first time the for loop runs:

for i in range(2):
    print(i)
    tmp2 = b()
    for j in tmp2:
        print(j)

The zip is iterated over:

0
(1, 2)
(2, 3)
(3, 4)
(4, 5)
(5, 6)
(6, 7)

The next time you call b() , the same zip iterator is returned. But you had just exhausted that iterator in the last loop. So there is nothing left in the iterator to go over, resulting in:

1

You can verify it by checking the id() of tmp :

print(id(tmp))

First loop:

2109174712000  # <- different IDs
(1, 2)
(2, 3)
(3, 4)
(4, 5)
(5, 6)
(6, 7)
2109174711872  # <- different
(1, 2)
(2, 3)
(3, 4)
(4, 5)
(5, 6)
(6, 7)
=======

Second loop:

0
2109174711936  # <- same ID
(1, 2)
(2, 3)
(3, 4)
(4, 5)
(5, 6)
(6, 7)
1
2109174711936  # <- same ID

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM