They’re somewhat more capable now that we have the walrus (
:=
) operator.Can you give an example? Can you use it to initialize vars outside the scope of the lambda?
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.
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 alist
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 IDi
is1261456
. 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 2student_recs[i]
look-ups to get each name which would be wasteful or replace the lambda with a regular function where you can writerec = student_recs[i]
on its own line and then use it.Am I making any sense?
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 atuple
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.