Python:按键排序遍历字典

84

我有一个Python字典

steps = {1:"value1", 5:"value2", 2:"value3"}
我需要按键进行排序并迭代。我尝试了这个:
x = sorted(steps, key=lambda key: steps[key])

但是 x 中的值已经消失了。

6个回答

119
我需要按键值的排序顺序进行迭代。我认为使用lambda表达式过于繁琐,试试这个:
>>> steps = {1:"val1", 5:"val2", 2:"val3"}
>>>
>>> for key in sorted(steps):
...     print steps[key]
...
val1
val3
val2

2
如果键是字符串,但我需要将其作为整数排序,该怎么办? - user984003
@jamylak 出于好奇,因为我不知道,为什么 sorted(steps)sorted(steps) 好?有性能差异吗? - circuitBurn
15
我知道这是一篇非常老的帖子,但我在搜索其他内容时遇到了它,并想记录一下: for key,value in sorted(steps): print valuefor key in sorted(steps): print steps[key]快得多。 - Dave LeBlanc
7
在回答中定义的步骤中,执行“for key,value in sorted(steps): print value”会出现“TypeError: 'int' object is not iterable”的错误 - 你是想执行“for key,value in sorted(steps.iteritems()): print value”吗? - Mr_and_Mrs_D
15
Python 3:for key, value in sorted(steps.items()): - Kirill Bulygin
显示剩余2条评论

35

你需要迭代 steps.items(),因为字典的迭代只会返回它的键。

>>> x = sorted(steps.items())
>>> x
[(1, 'value1'), (2, 'value3'), (5, 'value2')]

按排序后的键迭代:

>>> for key in sorted(steps):
...     # use steps[keys] to get the value

那么我该如何迭代它,比如使用iteritems或其他什么方法? - user984003
@user984003,你不能对字典进行排序,只能获取已排序的键、值或项列表。 - Ashwini Chaudhary
@AshwiniChaudhary,你根本不需要为sorted指定一个key,因为字典键本身就是唯一的,所以sorted(steps.items())完全可以正常工作。 - jamylak

7
您也可以使用Python的许多SortedDict容器类型之一。这些类型会自动按键顺序维护字典排序。请查看纯Python且与C实现一样快速的sortedcontainers模块。还有一个性能比较,对其他几个实现进行了基准测试。
在您的情况下,您将使用:
from sortedcontainers import SortedDict
steps = SortedDict({1:"value1", 5:"value2", 2:"value3"})

# Then iterate the items:

for key, value in steps.items():
    print key, value

# Or iterate the values:

for value in steps.values():
    print value

迭代键/值/项按照键的排序顺序自动进行。

5

如果您的键不是整数,而是应解析为整数的字符串:

steps = {'1':'value1', '10': 'value0', '5':'value2', '2':'value3'}

您可以使用类似您解决方案的方法:
for key in sorted(steps, key=lambda key: int(key)):
    print(key, steps[key])

1
2
5
10

1

正如Zagorulkin Dmitry所指出的那样,您不应该将lambda传递给排序函数。排序函数的默认行为是作用于键。

steps = {1:"val1", 5:"val2", 2:"val3"}

for key in sorted(steps):
   print steps[key]
...
val1
val3
val2

然而,将lambda传递给排序函数并不是更好的操作,只会带来微小的好处(即“过度设计”),实际上这是不期望的。它使代码不易读,并且速度较慢,特别是如果您要将其应用于非常大的字典或多次调用该函数。除了使排序目标相对于(键,值)对更明确之外,使用它没有任何好处。以下时间显示了指定lambda时会受到的性能损失。
steps = {randint(0, 100000): randint(0, 100000) for _ in range(100000) } # random dict

%%timeit 
sort_list = [value for _, value in sorted(steps.items(), key=lambda item: item[0])]
1 loops, best of 3: 241 ms per loop

%%timeit 
sort_list = [steps[k] for k in sorted(steps, key=lambda k: k)]
1 loops, best of 3: 196 ms per loop

%%timeit
sort_list = [ steps[key] for key in sorted(steps) ]
10 loops, best of 3: 106 ms per loop

0

根据您的使用情况,保持一个已经排序过的字典可能是一个好选择。请参考Python OrderedDict了解详细信息。如果您想将键按整数排序,则必须将它们转换为整数。最佳转换时机取决于您的使用情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接