1

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.

1
  • Think of a lambda as a short form of a function with an implied return statement, and you're good to go. Commented Jun 20, 2016 at 3:53

1 Answer 1

4

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)
Sign up to request clarification or add additional context in comments.

5 Comments

Sorry exercises was a typo the correct variable to sort is values. But that's the thing. I can't access values["date"] through the code but this lambda function still works. Why? As in, values is a list not a dictionary.
Values isn't referring to your list, it is the argument to a new function, thus it will mask that variable. It could be called x or element or whatever.
I've updated the answer to address the confusing parameter name in addition to the difference between a lambda and a normal function.
Oh I see so what's actually going on is that 'val' is one of the elements in the list 'values' (which is a dictionary that I can access using val["date"] or val["val"]. Am I understanding this correctly?
OHHH I get it thanks a bunch. So much more helpful than TigerhawkT3.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.