简体   繁体   中英

Eager evaluation of lambdas within a list comprehension

Consider a python function:

def testSetsFromStrings(tt):
  x1= [lambda x: x.split(' ') for t in tt]
  return x1

Let's invoke it with the following :

tt = ['id0 id1 id2 id3 id4', 
'id10 id11 id12 id13 id14', 
'id20 id21 id22 id23 id24', 
' id30 id31 id32 id33 id34', 
'id50 id51 id52 id53 id54']

testSetFromStrings(tt)

A breakpoint was placed after the x1= .. line and we can see x1 =

<class 'list'>: [<function testSetsFromStrings.<locals>.<listcomp>.
<lambda> at 0x11cee5730>, <function testSetsFromStrings.<locals>.<listcomp>.
<lambda> at 0x11cee5840>, <function testSetsFromStrings.<locals>.<listcomp>.
<lambda> at 0x11cee58c8>, <function testSetsFromStrings.<locals>.<listcomp>.
<lambda> at 0x11cee5950>, <function testSetsFromStrings.<locals>.<listcomp>.
<lambda> at 0x11cee59d8>]

I am at a loss as to how to cause that lambda to be eagerly evaluated. What can be done here?

** Update**

The logic shown is a simplification of the multi step function that is needed: to focus on just the mechanics of invoking a lambda. Replacing the lambda with directly invoking split does not address the real need.

Perhaps you don't want lambdas at all? Is this what you want?

def testSetsFromStrings(tt):
    x1 = [x.split(' ') for x in tt]
    return x1

Lambdas are functions: they are evaluated when you call them. If you want them to run immediately, then you probably don't need a lambda at all.

If you need to invoke a function, then invoke it:

def testSetsFromStrings(tt):
    x1 = [my_function(x) for x in tt]
    return x1

You're defining the function, but not applying any arguments to it:

Try this instead

x1 = [(lambda x: x.split(' '))(x) for x in tt]

But it would be better to just extract the function definition outside of the comprehension if the function is at all complicated and then use a map or list comprehension.

You could also use a map function instead of a list comprehension:

x1 = map(lambda x: x.split(' '), tt)

if you prefer the lamda function being present. Elsewhere just:

x1 = [x.split(' ') for x in tt]

as mentioned from others as well.

What you need to understand is that lambdas are inherently functions themselves. Therefore, create a lambda function and invoke that.

testSetsFromStrings = lambda x: x.split(' ')
x1 = [testSetsFromStrings(t) for t in tt]

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