如何按特定键的值对词典列表进行排序?鉴于:
[{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]
按名称排序时,应为:
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
如何按特定键的值对词典列表进行排序?鉴于:
[{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]
按名称排序时,应为:
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
当前回答
如果要按多个键对列表进行排序,可以执行以下操作:
my_list = [{'name':'Homer', 'age':39}, {'name':'Milhouse', 'age':10}, {'name':'Bart', 'age':10} ]
sortedlist = sorted(my_list , key=lambda elem: "%02d %s" % (elem['age'], elem['name']))
它相当粗糙,因为它依赖于将值转换为单个字符串表示形式进行比较,但对于包括负数在内的数字,它的工作方式与预期一样(尽管如果使用数字,则需要使用零填充来适当地格式化字符串)。
其他回答
假设我有一本字典D,其中包含以下元素。要排序,只需使用sorted中的key参数传递自定义函数,如下所示:
D = {'eggs': 3, 'ham': 1, 'spam': 2}
def get_count(tuple):
return tuple[1]
sorted(D.items(), key = get_count, reverse=True)
# Or
sorted(D.items(), key = lambda x: x[1], reverse=True) # Avoiding get_count function call
看看这个。
我一直是lambda过滤器的忠实粉丝。然而,若考虑到时间复杂性,这并不是最好的选择。
第一个选项
sorted_list = sorted(list_to_sort, key= lambda x: x['name'])
# Returns list of values
第二个选项
list_to_sort.sort(key=operator.itemgetter('name'))
# Edits the list, and does not return a new list
快速比较执行时间
# First option
python3.6 -m timeit -s "list_to_sort = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}, {'name':'Faaa', 'age':57}, {'name':'Errr', 'age':20}]" -s "sorted_l=[]" "sorted_l = sorted(list_to_sort, key=lambda e: e['name'])"
1000000个循环,最好为3个:每个循环0.736µsec
# Second option
python3.6 -m timeit -s "list_to_sort = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}, {'name':'Faaa', 'age':57}, {'name':'Errr', 'age':20}]" -s "sorted_l=[]" -s "import operator" "list_to_sort.sort(key=operator.itemgetter('name'))"
1000000个循环,最好为3个:每个循环0.438µsec
如果要按多个键对列表进行排序,可以执行以下操作:
my_list = [{'name':'Homer', 'age':39}, {'name':'Milhouse', 'age':10}, {'name':'Bart', 'age':10} ]
sortedlist = sorted(my_list , key=lambda elem: "%02d %s" % (elem['age'], elem['name']))
它相当粗糙,因为它依赖于将值转换为单个字符串表示形式进行比较,但对于包括负数在内的数字,它的工作方式与预期一样(尽管如果使用数字,则需要使用零填充来适当地格式化字符串)。
sorted()函数接受key=参数
newlist = sorted(list_to_be_sorted, key=lambda d: d['name'])
或者,您可以使用operator.itemgetter而不是自己定义函数
from operator import itemgetter
newlist = sorted(list_to_be_sorted, key=itemgetter('name'))
为完整起见,添加reverse=True以降序排序
newlist = sorted(list_to_be_sorted, key=itemgetter('name'), reverse=True)
如果性能是一个问题,我会使用operator.itemgetter而不是lambda,因为内置函数比手工制作的函数执行得更快。根据我的测试,itemgetter函数的执行速度似乎比lambda快20%左右。
从…起https://wiki.python.org/moin/PythonSpeed:
同样,内置函数的运行速度也比手工构建的等效函数快。例如,map(operator.add,v1,v2)比map(lambda x,y:x+y,v1,v2)更快。
下面是lambda与itemgetter排序速度的比较。
import random
import operator
# Create a list of 100 dicts with random 8-letter names and random ages from 0 to 100.
l = [{'name': ''.join(random.choices(string.ascii_lowercase, k=8)), 'age': random.randint(0, 100)} for i in range(100)]
# Test the performance with a lambda function sorting on name
%timeit sorted(l, key=lambda x: x['name'])
13 µs ± 388 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# Test the performance with itemgetter sorting on name
%timeit sorted(l, key=operator.itemgetter('name'))
10.7 µs ± 38.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# Check that each technique produces the same sort order
sorted(l, key=lambda x: x['name']) == sorted(l, key=operator.itemgetter('name'))
True
这两种技术都以相同的顺序对列表进行排序(通过在代码块中执行最终语句来验证),但第一种排序速度稍快。