Home >Backend Development >Python Tutorial >Why Do Lambda Functions in Loops in Python Exhibit Unexpected Behavior?

Why Do Lambda Functions in Loops in Python Exhibit Unexpected Behavior?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-28 10:35:11107browse

Why Do Lambda Functions in Loops in Python Exhibit Unexpected Behavior?

Lambda in a Loop: Understanding Default Closure Parameters

In Python programming, lambda functions are anonymous functions that can be used to create dynamic code blocks. However, when using lambdas in loops, one may encounter unexpected behavior. This article explores the issue and provides solutions.

Consider the following code snippet:

# directorys == {'login': <object at ...>, 'home': <object at ...>}
for d in directorys:
    self.command["cd " + d] = (lambda: self.root.change_directory(d))

The goal is to create a dictionary self.command that maps commands to functions. Each function should change the directory to the specified value in directorys. However, the result is unexpected:

# Expected:
self.command == {
    "cd login": lambda: self.root.change_directory("login"),
    "cd home": lambda: self.root.change_directory("home")
}

# Result:
self.command == {
    "cd login": lambda: self.root.change_directory("login"),
    "cd home": lambda: self.root.change_directory("login")  # <- Why login?
}

The issue arises because lambda functions created in a loop share the same closure. When d is updated in the loop, it affects all lambda functions, causing them to refer to the same variable.

Solution: Using Default Closure Parameters

To resolve this, introduce default closure parameters. Here's how:

lambda d=d: self.root.change_directory(d)

By passing d as a parameter with a default value, the function within the lambda references its own parameter instead of the loop variable. This ensures that each function changes the directory to the intended value.

# Another way to bind d:
lambda bound_d=d: self.root.change_directory(bound_d)

Remember that default values for mutable objects (like lists and dicts) are shared, so be cautious when binding these types.

Additional Closure Techniques

If passing default parameters is not ideal, try these alternative closure techniques:

  • Nested closures:

    (lambda d: lambda: self.root.change_directory(d))(d)
  • Immediate invocation:

    (lambda d=d: lambda: self.root.change_directory(d))()

The above is the detailed content of Why Do Lambda Functions in Loops in Python Exhibit Unexpected Behavior?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn