Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

356
Views
How is `x = 42; x = lambda: x` parsed?

I was surprised that this assertion fails:

x = 42
x = lambda: x
assert x() == 42

It seems that x ends up recursively referring to itself, so that x(), x()(), etc. are all functions.

What is the rule used to parse this, and where is this documented?

By the way (not unexpectedly given the above), the original value of x has no references left after the lambda definition:

class X:
  def __del__(self): print('deleting')

x = X()
x = lambda: x  # 'deleting' is printed here
over 4 years ago · Hanz Gallego
3 answers
Answer question

0

The first assignment is irrelevant; the x in the body of the lambda is bound late:

x = lambda: x # no need for a prior assignment
x = lambda: y # notice: no NameError occurs, *until it is called*

This is the same reason that creating lambdas in a loop is tricky, and is also used to make trees with the standard library defaultdict:

tree = lambda: defaultdict(tree)
t = tree()
t['foo']['bar']['baz'] = 'look ma, no intermediate steps'
over 4 years ago · Hanz Gallego Report

0

A lambda is an anonymous function object. Python completely resolves whatever is on the right side of an equation to a single anonymous object and then resolves whatever is on the left side for assignment.

x = lambda: x

first compiles lambda: x into a function object that returns whatever happens to be in x at the time it is called. It then rebinds x with this function object, deleting whatever object happened to be there before.

Now x is a function that returns whatever is in x... which is a function that returns whatever is in x, etc... So you can write x()()()()()() as many times as you want, and still get that orginal lambda:x function object.

Python functions have a local namespace but only variables assigned in the function reside there. Since x isn't assigned in the lambda, it's resolved in the containing scope - that is, the module level "x". An identical piece of code is

def x():
    return x

Contrast this with

def x():
    x = 1
    return x

Now, the parameter x is a local variable and is unrelated to the global x.

over 4 years ago · Hanz Gallego Report

0

The variable x is created by the first assignment, and rebound with the second assignment.

Since the x in the lambda isn't evaluated until the lambda is called, calling it will evaluate to the most recently assigned value.

Note that this is not dynamic scoping - if it were dynamic, the following would print "99", but it prints "<function ...":

x = 42
x = lambda: x

def test(f):
  x = 99
  print(f())

test(x)
over 4 years ago · Hanz Gallego Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!