I'm using python 2.7.3, and I'm trying to sort a list of dictionaries based on the order of values of another list.
IE:
listOne = ['hazel', 'blue', 'green', 'brown']
listTwo = [{'name': 'Steve', 'eyecolor': 'hazel', 'height': '5 ft. 11 inches'},
{'name': 'Mark', 'eyecolor': 'brown', 'height': '6 ft. 2 inches'},
{'name': 'Mike', 'eyecolor': 'blue', 'height': '6 ft. 0 inches'},
{'name': 'Ryan', 'eyecolor': 'brown', 'height': '6 ft, 0 inches'},
{'name': 'Amy', 'eyecolor': 'green', 'height': '5 ft, 6 inches'}]
Sorting listTwo based off of the order of values in listOne, we would end up with the following:
print listTwo
[{'name': 'Steve', 'eyecolor': 'hazel', 'height': '5 ft. 11 inches'},
{'name': 'Mike', 'eyecolor': 'blue', 'height': '6 ft. 0 inches'},
{'name': 'Amy', 'eyecolor': 'green', 'height': '5 ft, 6 inches'},
{'name': 'Mark', 'eyecolor': 'brown', 'height': '6 ft. 2 inches'},
{'name': 'Ryan', 'eyecolor': 'brown', 'height': '6 ft, 0 inches'}]
I eventually need to output this text, so what I've done to display it correctly (in the correct order) is the following:
for x in xrange(len(listOne)):
for y in xrange(len(listTwo)):
if listOne[x] == listTwo[y]["eyecolor"]:
print "Name: " + str(listTwo[y]["name"]),
print "Eye Color: " + str(listTwo[y]["eyecolor"]),
print "Height: " + str(listTwo[y]["height"])
Is there some sort of lambda expression that can be used to make this happen? There has to be a more compact, less complex way of getting it in the order I want.
To correctly sort a dictionary by value with the sorted() method, you will have to do the following: pass the dictionary to the sorted() method as the first value. use the items() method on the dictionary to retrieve its keys and values. write a lambda function to get the values retrieved with the item() method.
Using a Lambda FunctionWe can use Python function sorted() with lambda function to sort a dictionary by value.
Solution: You have two main ways to do this—both are based on defining the key function of Python's sorting methods. The key function maps each list element (in our case a dictionary) to a single value that can be used as the basis of comparison. Use a lambda function as key function to sort the list of dictionaries.
Since dictionaries in Python 3.5 don't remember the order of their items, you don't know the order in the resulting ordered dictionary until the object is created. From this point on, the order is maintained. Since Python 3.6, functions retain the order of keyword arguments passed in a call.
The simplest way would be to use list.index
to generate a sort value for your list of dictionaries:
listTwo.sort(key=lambda x: listOne.index(x["eyecolor"]))
This is a little bit inefficient though, since list.index
does a linear search through the eye-color list. If you had many eye colors to check against, it would be slow. A somewhat better approach would build an index dictionary instead:
order_dict = {color: index for index, color in enumerate(listOne)}
listTwo.sort(key=lambda x: order_dict[x["eyecolor"]])
If you don't want to modify listTwo
, you can use the built-in sorted
function instead of the list.sort
method. It returns a sorted copy of the list, rather than sorting in-place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With