34
you are viewing a single comment's thread
view the rest of the comments
[-] tunetardis@lemmy.ca 5 points 4 months ago

They're somewhat more capable now that we have the walrus (:=) operator.

[-] BeefPiano@lemmy.world 2 points 4 months ago

Can you give an example? Can you use it to initialize vars outside the scope of the lambda?

[-] tunetardis@lemmy.ca 5 points 4 months ago

Can you use it to initialize vars outside the scope of the lambda?

No, that's not what it's for. It lets you define a temporary local variable within an expression. This is useful in situations where you might want to use the same value more than once within the expression. In a regular function, you would just define a variable first and then use it as many times as you want. But until the walrus operator came along, you couldn't define a variable within a lambda expression.

Can you give an example?

Ok, I'm trying to think of a simple example. Let's say you had a database that maps student IDs to records contain their names. To keep things simple, I'll just make it plain old dict. And then you have a list of student IDs. You want to sort these IDs using the student names in the form "last, first" as the key. So you could go:

>>> student_recs = {1261456: {"first": "Harry", "last": "Potter"}, 532153: {"first": "Ron", "last": "Weasley"}, 632453: {"first": "Hermione", "last": "Granger"}}
>>> student_ids = [1261456, 532153, 632453]
>>> sorted(student_ids, key = lambda i: (rec := student_recs[i])['last'] + ', ' +  rec['first'])
[632453, 1261456, 532153]

The problem here is that student_ids doesn't contain the student names. You need use the ID to look up the record that contains those. So let's say the first ID i is 1261456. That would mean:

rec := student_recs[i]

evaluates to:

{"first": "Harry", "last": "Potter"}

Then we are effectively going:

 rec['last'] + ', ' + rec['first']

which should give us:

 'Potter, Harry'

Without the := you would either have to perform 2 student_recs[i] look-ups to get each name which would be wasteful or replace the lambda with a regular function where you can write rec = student_recs[i] on its own line and then use it.

Am I making any sense?

[-] tunetardis@lemmy.ca 2 points 4 months ago

Actually, now that I think of it, there's no reason you need to join the 2 names into a single str. You could just leave it as a tuple of last, first and Python will know what to do in comparing them.

>>> sorted(student_ids, key = lambda i: ((rec := student_recs[i])['last'], rec['first']))
[632453, 1261456, 532153]

So the lambda would be returning ('Potter', 'Harry') rather than 'Potter, Harry'. But whatever. The := part is still the same.

[-] sugar_in_your_tea@sh.itjust.works 2 points 4 months ago

The general form is:

(var := expression) rest of condition

So you can do something awful like this:

lambda: (y := 1) != 2 and y

Not sure if that's "good," but it does kind of let you sneak a statement into the lambda.

this post was submitted on 29 Apr 2024
34 points (100.0% liked)

Python

6187 readers
48 users here now

Welcome to the Python community on the programming.dev Lemmy instance!

📅 Events

October 2023

November 2023

PastJuly 2023

August 2023

September 2023

🐍 Python project:
💓 Python Community:
✨ Python Ecosystem:
🌌 Fediverse
Communities
Projects
Feeds

founded 1 year ago
MODERATORS