I've encountered an issue re scopes in a lambda
function. I can successfully output foo to stdout but I get an error when using max()
including a lambda
- see simplified code below...
All in all, I am trying find the largest value for a nested key budget
within an unknown number of first order keys.
(Pdb) foo = self.some_method() # some_method() returns a dict, printed in the next step
(Pdb) pp foo
{'1': {'count': 1,
'extra_data': {'activity-count': 1,
'budget': 0,
[...MORE KEY-VALUE PAIRS HERE...]
'version': 1},
[...LOTS MORE KEY-VALUE PAIRS HERE...]
'elements_total': defaultdict(<type 'int'>, {'result': 1, 'another_key': 2}),
'extra_year_data': defaultdict(<function <lambda> at 0x10e05bd70>, {})},
'2': {'count': 1,
'extra_data': {'activity-count': 1,
'budget': 3,
[...MORE KEY-VALUE PAIRS HERE...]
'version': 1},
[...LOTS MORE KEY-VALUE PAIRS HERE...]
'elements_total': defaultdict(<type 'int'>, {'result': 1, 'another_key': 2}),
'extra_year_data': defaultdict(<function <lambda> at 0x10e05bd70>, {})}}
(Pdb) max(foo, key=lambda x: foo[x]['extra_data']['budget'])
*** NameError: global name 'foo' is not defined
All in all, I am trying to use max(foo, key=lambda x: foo[x]['extra_data']['budget'])
to find the largest value for a nested key budget
within an unknown number of first order keys.
The expected result in this case could be 2
as the value for foo['2']['extra_data']['budget'] = 3
vs. foo['1']['extra_data']['budget'] = 0
.
Could the error be related to the fact that some of the (unrelated) keys have defaultdict
s within them?
The Python "NameError: name is not defined" occurs when we try to access a variable or function that is not defined or before it is defined. To solve the error, make sure you haven't misspelled the variable's name and access it after it has been declared.
Optionally, you can also tell pdb to break only when a certain condition is true. Use the command b (break) to set a breakpoint. You can specify a line number or a function name where execution is stopped. If filename: is not specified before the line number lineno , then the current source file is used.
If you run it from a Python shell, then __file__ is not defined unless you import the code as a module.
NameError: global name '---' is not definedOther names are defined within the program (such as variables). If Python encounters a name that it doesn't recognize, you'll probably get this error. Some common causes of this error include: Forgetting to give a variable a value before using it in another statement.
You set a new local with pdb
, but that is not visible to expressions using nested scopes in this debugger session. Any expression in a nested scope such as the lambda
used for the key
argument, using a name that is local to the current frame, would need to be a closure and will have this problem.
That's a limitation of how the debugger and Python compilation work; closures can only be created if the function that need to produce them was compiled in the same session. Since the function you are debugging was compiled without foo
being a closure, it cannot be used by the lambda
expression as such.
You can bind the local to the lambda (making it a local rather than a closure):
max(foo, key=lambda x, foo=foo: foo[x]['extra_data']['budget'])
See What exactly is contained within a obj.__closure__? for details on how the Python compiler creates closures.
There is a bug report for Python 3 (however this issue affects Python 2.7 as well as you found out) which suggests a workaround as an alternative to Martijn's solution: interact
at the pdb
prompt drops you into an interactive session which is populated with globals()
and locals()
and your lambda
should work as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With