9

On reading through some code, I came across the below snippet which I am not able to understand. Would anyone be able to guide/provide hints/link or a basic explanation of line 3 below

def do_store(*args, **kwargs):
    try:
        key = (args, tuple(sorted(kwargs.items(), key=lambda i:i[0])))
        results = f._results

mainly, what is the following doing?

key=lambda i:i[0]
0

5 Answers 5

12

With the lambda keyword, you create "anonymous functions". They don't have (and don't need to have) a name, because they are immediately assigned (usually) to a callback function.

lambda i:i[0]

is just the body of the function

def f(i):
  return i[0]

The key parameter of the sorted function has to be a function that computes sorting key for a given item. You could also pass the function (name) f as defined above, or use a lambda function for better readability.

As stated in tobias_k's answer, in this piece of code, the whole key parameter is useless.

Sign up to request clarification or add additional context in comments.

1 Comment

It might be worth pointing out that your second code block is actually equivalent to f=lambda i:i[0]. Without assigning it a name, a lambda function is nothing.
9

The other answers already explain well what lambda and sorted's key parameter do. In short:

  • key is used to provide a comparison key function for the sort, lets call it f, such that if f(x) < f(y), then x will appear before y in the sorted list.
  • the lambda creates such a function in a quick and tidy way, without the need to create a def just for that one sort; you can just as well use any other function (your own definitions, builtins, etc.)

However, to answer the question what key=lambda i:i[0] does, in your code: Nothing at all!

More precisely, it tells sorted to sort by the first element of the tuples that are in the list to be sorted, which is produced by kwargs.items(), i.e. a list of (key, value) tuples. But sorting by the first element is the default sorting behaviour for tuples anyway, and only if those are equal, it would sort by the second element, and so on. But since those are the (keys, values) of a dictionary, there are no two tuples with the same first element, so using this particular key function is exactly the same as the default sort.

You can just as well use key = (args, tuple(sorted(kwargs.items()))).

If you are asking why it does this: This function seems to be used for memoization, mapping the function parameters (stored in args and kwargs) to previously calculated values. For this, the kwargs dictionary has to be transformed to a tuple, because a dictionary is not hashable, i.e. it can not be used as the key to another dictionary. And in order to ensure that the same dictionaries always result in the same tuples, it has to be sorted, because dictionaries are unordered.

Comments

7

Three equivalent ways to write this:

sorted(kwargs.items(), key=lambda i:i[0])

(which is the one you have)

def first_item(aList): return aList[0]
sorted(kwargs.items(), key=first_item)

from operator import itemgetter
sorted(kwargs.items(), key=itemgetter(0))

In all cases the argument key is passed a function taking one parameter and returning the the first element of that parameter.

The lambda is simply a shorthand that avoids giving a name to the function. Giving the function a name may help people reading the code, especially if the expression is more complex. The itemgetter function has a slight speed advantage but isn't as flexible as all it can do is return one or more items; if you wanted to manipulate the items further (e.g. lower case them) you have to use either a def or lambda.

Comments

4

Without mentioning second argument, , key=lambda i:i[0], kwargs would be sorted just by their full names. For example in call

do_store(abc=1, xyz=2, nji=3)

kwargs is a dict {abc: 1, xyz: 2, nji: 3} and sorted(kwargs.items()) would be [('abc', 1), ('nji', 3), ('xyz', 2)]. And default key is simply lambda i: i (i.e. for each element in kwargs we use the elemnt itself for comparison). In you example we will use only the first object of item (i.e. only the dict key because item is a pair (key, value))

Comments

1

Lambda allows you to create simple, anonymous functions using an expression. In this case the anonymous function accepts a single argument 'i' and returns the element within 'i' at index zero.

It's purpose in this case is to create a function that selects a sorting key to be used by the 'sorted()' function.

Comments

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.