Reputation: 961
So I have a list of values like so:
{
"values":
[
{
"date": "2015-04-15T11:15:34",
"val": 30
},
{
"val": 90,
"date": "2015-04-19T11:15:34"
},
{
"val": 25,
"date": "2015-04-16T11:15:34"
}
]
}
that I'm parsing in with pythons deafault json parser into a list like so:
with open(file) as f:
data = json.load(f)
values = data["values"]
I'm then trying to sort the data by date like so:
values.sort(key=lambda values: values["date"])
And this works (to my knowledge). My question is why does it work? If I can't access values["date"] then why can I use this lambda function? values can't take a key like "date" only an integer. What I mean by this is I can only access values like so: values[0], values[1], etc... because it's a list not a dictionary. So if this lambda functions equivalent is this:
def some_method(values):
return values[“date”]
then this is invalid because values is a list not a dictionary. I can't access values["date"].
So why can I just pass in the date through the function like this? Also if you could explain lambda in depth that would be appreciated. I've read other posts on stack overflow about it but they just don't make sense to me.
Updated question with more information to make the problem more clear.
Upvotes: 1
Views: 1209
Reputation: 104712
A lambda
expression is simply a concise way of writing a function. It's especially handy in cases like the one you give where you only need to use the function once, and it needs to be used as an expression (e.g. an argument to a function).
Here's an alternative version of your example, using def
statement instead of a lambda
expression:
def keyfunc(values):
return values["date"]
values.sort(key=keyfunc)
That's two lines longer, and leaves behind an extra variable in the current namespace. If the lambda version is just as clear as the def
version, it's generally a better choice.
It looks like your confusion may come from the extra use of the name values
in the function. That's simply a poorly chosen argument name. The list.sort
method will call the key
function once for each value in the list, passing the value as the first positional argument. That value will be bound to whatever variable name is used in the function declaration (regardless of whether it's a def
or a lambda
). In your example, a better name might be val
or item
, since it's going to be just a single item from the values
list. The name could really be whatever you want (and indeed, values
works fine, it just looks confusing). This would be clearer:
values.sort(key=lambda val: val["date"])
Or:
def keyfunc(val):
return val["date"]
values.sort(key=keyfunc)
Upvotes: 4