> For the complete documentation index, see [llms.txt](https://wiki.theconfused.me/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.theconfused.me/programming/python/closures-in-python-capture-variables-not-values.md).

# Closures in Python capture variables, not values

```python
def random_function(s):
    print(s)

letters = []
for s in ["a", "b", "c"]:
    letters.append((s, lambda : random_function(s)))

for url, f in letters:
    f()
```

This prints&#x20;

```
c
c
c
```

The reason is that the argument is only evaluated when the function is executed.&#x20;

The way to workaround this is to set it as a default value ("the default-value hack"):

```python
def random_function(s):
    print(s)

letters = []
for s in ["a", "b", "c"]:
    letters.append((s, lambda s=s: random_function(s)))

for url, f in letters:
    f()
```

The reason this works is that [default values are created once, when the function is defined](https://docs.python.org/3/faq/programming.html#why-are-default-values-shared-between-objects). This will print

```
a
b
c
```
