1

I try to create a dictionary of string formatting lambda functions, but for some (to me) obscure reason, it's not working, and the incorrect value is retrieved from the dictionary; see the use of the ffuncs dictionary, below.

value = 12345.6789

fstrings = {"a": "{:,.2f}", "b": "{:,.5f}"}
print(fstrings["a"].format(value).replace(",", " "))  # 12 345.68

ffuncs = {}
for key, fstring in fstrings.items():
    ffunc = lambda v: fstring.format(v).replace(",", " ")
    ffuncs[key] = ffunc
    if key == "a":
        print(id(ffunc))  # 2020101253584
        print(ffunc(value))  # 12 345.68  <-- here it's still working

print(id(ffuncs["a"]))  # 2020101253584 <-- same function...
print(ffuncs["a"](value))  # 12 345.67890 <-- ...but 5 decimal places??

Seems incredibly basic, but I can't figure it out. Many thanks.

ElRudi
  • 2,122
  • 2
  • 18
  • 33
  • Have a look at [this answer](https://stackoverflow.com/a/34854542/7947994). Iterating with lambdas somehow remembers only the last value. – JANO Jan 16 '22 at 18:40
  • Aside: Using named `lambda` statements is un-Pythonic (and difficult to read/debug); a `def` should be used instead. Think of the meaning of a `lambda` statement: “An anonymous function.” Once named, it’s no longer anonymous, therefore breaks Python-design convention. – S3DEV Jan 16 '22 at 18:47
  • @S3DEV: I agree. I only named the functions for debugging purpose. The middle section used to be `ffuncs = {key: lambda v: fstring.format(v).replace(",", " ") for key, fstring in fstrings.items()}`, and was only expanded to find the error. – ElRudi Jan 16 '22 at 18:49
  • @JANO - many thanks, I had no idea! Having spent hours and hours on finding the error, this seems like a design flaw to me. I will definitely not be using `lambda` expressions in loops or comprehensions ever again! – ElRudi Jan 16 '22 at 18:51

0 Answers0