简体   繁体   中英

exec() with nested loop in list comprehension inside function error

exec() from inside a function gives a different output, even I pass all the parameter needed to that function. Consider this code:

def list_filter(expr,datalist,includelist) :
    exec(expr)
    print outlist


datalist=['try to kill me','black image']
includelist=['me']
expr="outlist = [i for i in datalist if  all(j in i for j in includelist)  ]"
exec(expr)
print outlist
list_filter(expr,datalist,includelist)

I have checked the similar case here : How does exec work with locals?

But this is a different error, where I'm using version 2.7.13 and I check under general condition, the exec() normally has no error at all. I found this problem shows up when there's a 'nested loop' inside list comprehension statement, such as using all() or any() . As in this case , if I remove the if condition from the list comprehension (make it to be expr = "outlist = [i for i in datalist ]" ) then I will get the correct output as usual.

Any idea why?

Almost always it's a bad idea to use exec in this case you probably shouldn't use it at all.

But since you asked: It works correctly if you pass in the variables from the local scope:

def list_filter(expr, datalist, includelist):
    exec(expr, locals())
    print outlist

I'm not very familiar with the scope rules for exec but I often found that you need to pass in the variables explicitly (especially if the exec isn't in the global scope).

In your case you could even pass them in explicitly:

def list_filter(expr, datalist, includelist):
    exec(expr, {'datalist': datalist, 'includelist': includelist})
    print outlist

It's even stated in the documentation that you may need to pass the variables from the scope to exec :

The built-in functions globals() and locals() return the current global and local dictionary, respectively, which may be useful to pass around for use by exec .

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