Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
182 views
in Technique[技术] by (71.8m points)

python - Sorting a list of dictionaries based on the order of values of another list

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...