Python Forum
Sorting list of names using a lambda (PyBite #5) - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Sorting list of names using a lambda (PyBite #5) (/thread-30332.html)



Sorting list of names using a lambda (PyBite #5) - Drone4four - Oct-16-2020

Working on CodeChallenges’ PyBite #5, here is the list I am working with:

names = ['arnold schwarzenegger', 'alec baldwin', 'bob belderbos',
        'julian sequeira', 'sandra bullock', 'keanu reeves',
        'julbob pybites', 'bob belderbos', 'julian sequeira',
        'al pacino', 'brad pitt', 'matt damon', 'brad pitt']
I am trying to return the names list (above) and sorted desc by surname. Leveraging this answer on Stack Overflow, here is my working solution:

def sort_by_surname_desc(names):
   return sorted(names, key=lambda x: x.split()[1], reverse=True)
What I understand:
  • The sorted built-in takes three parameters.
  • The first parameter is a mutable iterable (in my case list of names).
  • The second parameter is a key which needs to be callable like another function or in my case a lambda. According to the official Python docs, the key is called exactly once for each iterable. The official Python docs, when describing how to use sorted(), for the key parameter they also use a lambda.
  • In my code sample,the .split cuts up each list item string into two and pulls each second result as specified by [1].
  • The final parameter specifies that the list be sorted alphabetically in reverse.

What I don’t understand:
  • The lambda
W3schools has a tutorial on lambdas which uses this example:

 def myfunc(n):
  return lambda a : a * n
mydoubler = myfunc(2)
print(mydoubler(11))
The output is 22. The lambda expression throws me off. I re-wrote myfunc() which produces the same output but uses a regular function:

def my_second_func(n, a):
	return n * a
print(my_second_func(11,2))
I still don't understand. The Python docs describe lambda expressions in this way:

Quote:
lambda_expr       ::=  "lambda" [parameter_list] ":" expression
lambda_expr_nocond ::=  "lambda" [parameter_list] ":" expression_nocond
Lambda expressions (sometimes called lambda forms) are used to create anonymous functions. The expression lambda parameters: expression yields a function object. The unnamed object behaves like a function object defined with:
def <lambda>(parameters):
    return expression
See section Function definitions for the syntax of parameter lists. Note that functions created with lambda expressions cannot contain statements or annotations.

This doc is short and not all that helpful.

What might you people add to my discussion of lambdas? Dance How would you explain or breakdown the syntax of the lambda expression above or other lambda expressions elsewhere?


RE: Sorting list of names using a lambda (PyBite #5) - bowlofred - Oct-16-2020

A lambda is a just a function without a name (hence "anonymous"). You can certainly use a named function if it helps you understand it better.

def second_element(s):
    """Return the second element of the string after split()ing"""
    """Will raise IndexError if there are not two elements"""
    return s.split()[1]
    

def sort_by_surname_desc(names):
   return sorted(names, key=second_element, reverse=True)
The benefit of lambda is that if the function is super short, you don't have to define it elsewhere. You can just define it where it's used.


RE: Sorting list of names using a lambda (PyBite #5) - ndc85430 - Oct-16-2020

(Oct-16-2020, 12:46 PM)Drone4four Wrote: W3schools has a tutorial on lambdas which uses this example:

 def myfunc(n):
  return lambda a : a * n
mydoubler = myfunc(2)
print(mydoubler(11))

I think the way they've written this example adds to your confusion. There's no need to use a lambda here; it's just an unnecessary extra level of indirection.

It's better to see passing a function to another where it actually makes sense to do so. In the case of sorted, as you've seen, it allows you to customise the way the sorting is done. Other examples are map which allows you to transform each of the elements in an iterable, where the function you pass specifies how to transform an element; or filter, where the function you pass allows you to define which items to keep:

>>> names = ["Kernighan", "Ritchie",  "Thompson"]
>>> list(map(lambda name: name.upper(), names))
['KERNIGHAN', 'RITCHIE', 'THOMPSON']
>>> values = [1, 2, 3, 4, 5]
>>> list(filter(lambda x: x % 2 == 0, values))
[2, 4]
Of course, you could do the same with list comprehensions here.