Python Forum
Sorting list of names using a lambda (PyBite #5)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Sorting list of names using a lambda (PyBite #5)
#1
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?
Reply
#2
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.
ndc85430 and GOTO10 like this post
Reply
#3
(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.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  List Sorting Problem ZZTurn 5 1,279 Sep-22-2022, 11:23 PM
Last Post: ZZTurn
  Sorting List finndude 9 2,390 Jan-27-2022, 09:37 PM
Last Post: Pedroski55
  sorting a list of lists by an element leapcfm 3 1,805 Sep-10-2021, 03:33 PM
Last Post: leapcfm
  List comprehension and Lambda cametan 2 2,196 Jun-08-2021, 08:29 AM
Last Post: cametan
  Uses cases for list comprehension (encountered while doing PyBite #77) Drone4four 3 2,739 Sep-25-2020, 12:14 PM
Last Post: ndc85430
  Using my REPL to bisect numbers and lists with classes (PyBite #181) Drone4four 2 2,005 Sep-24-2020, 01:47 PM
Last Post: Drone4four
  Counting vowels in a string (PyBite #106) Drone4four 4 2,205 Jul-07-2020, 05:29 AM
Last Post: theknowshares
  list sorting question DPaul 5 2,718 Jun-17-2020, 02:23 PM
Last Post: ndc85430
  Topic: “Filter numbers with a list comprehension” (PyBite #107) Drone4four 4 2,311 Jun-11-2020, 08:31 PM
Last Post: Drone4four
  Conditionals, while loops, continue, break (PyBite 102) Drone4four 2 2,922 Jun-04-2020, 12:08 PM
Last Post: Drone4four

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020