排序字典python 3

Jja*_*ang 32 python dictionary

我正在研究python 3.2.2.打破我的脑袋超过3个小时按键排序字典.我设法使它成为一个带有2个参数成员的排序列表,但最终不能使它成为一个排序的字典.

这就是我的想法:

myDic={10: 'b', 3:'a', 5:'c'}
sorted_list=sorted(myDic.items(), key=lambda x: x[0])
Run Code Online (Sandbox Code Playgroud)

但无论我怎么做不出这个排序列表的字典.我怎么做?谢谢!

Mik*_*rek 42

dict不保持其元素的顺序.你需要的是一个OrderedDict:http://docs.python.org/library/collections.html#collections.OrderedDict

编辑

用法示例:

>>> from collections import OrderedDict
>>> a = {'foo': 1, 'bar': 2}
>>> a
{'foo': 1, 'bar': 2}
>>> b = OrderedDict(sorted(a.items()))
>>> b
OrderedDict([('bar', 2), ('foo', 1)])
>>> b['foo']
1
>>> b['bar']
2
Run Code Online (Sandbox Code Playgroud)

  • @Jjang,`OrderedDict = {}`只创建一个名为"OrderedDict"的普通字典.你需要做`from collections import OrderedDict`,然后用`myOrdDic = OrderedDict()`初始化. (4认同)
  • 但最后它仍然是一个列表,而不是一个字典......当你打印OrderedDict时,它打印成一个列表,带(),而不是{}就像一个字典...... (2认同)
  • 这最近已经过时了:因为 Python 3.7 字典是有序的。请参阅以下答案(以及这篇有趣的帖子https://softwaremaniacs.org/blog/2020/02/05/dicts-ordered/en/) (2认同)

Gra*_*ntJ 17

我认为你不想要OrderedDict.听起来你更喜欢SortedDict,这是一个按排序顺序维护其键的字典.所述sortedcontainers模块提供了这样的数据类型.它是用纯Python编写的,快速实现C,具有100%的覆盖率和数小时的压力.

使用pip轻松安装:

pip install sortedcontainers
Run Code Online (Sandbox Code Playgroud)

请注意,如果您不能,pip install那么您只需从开源存储库中提取源文件即可.

那么你的代码很简单:

from sortedcontainers import SortedDict
myDic = SortedDict({10: 'b', 3:'a', 5:'c'})
sorted_list = list(myDic.keys())
Run Code Online (Sandbox Code Playgroud)

sortedcontainers模块还与其他流行的实现保持性能比较.

  • 对于使用Anaconda的用户,现在可以使用`conda install sortedcontainers`作为conda安装 (2认同)

kra*_*ski 17

适用于Python 3.7的现代快速解决方案.也可以在Python 3.6的一些解释器中工作.

TLDR

要按键对字典排序,请使用:

sorted_dict = {k: disordered[k] for k in sorted(disordered)}
Run Code Online (Sandbox Code Playgroud)

比接受的答案快三倍; 包含导入时可能更多.

评论接受的答案

在接受的答案中的示例而不是仅仅通过key参数sorted()或dict迭代的默认行为迭代键 - 迭代元组(key, value),这令人惊讶地证明比仅比较键和访问列表理解中的字典元素要慢得多.

如何在Python 3.7中按键排序

Python 3.7的重大变化是字典现在默认排序.

  • 您可以使用dict理解生成排序的dict.
  • OrderedDict出于兼容性考虑,使用可能仍然是优选的.
  • 不要sorted(d.items())没用key.

看到:

disordered = {10: 'b', 3: 'a', 5: 'c'}

# sort keys, then get values from original - fast
sorted_dict = {k: disordered[k] for k in sorted(disordered)}

# key = itemgetter - slower
from operator import itemgetter
key = itemgetter(0)
sorted_dict = {k: v for k, v in sorted(disordered.items(), key=key)}

# key = lambda - the slowest
key = lambda item: item[0]
sorted_dict = {k: v for k in sorted(disordered.items(), key=key)} 
Run Code Online (Sandbox Code Playgroud)

时间结果:

Best for {k: d[k] for k in sorted(d)}: 7.507327548999456
Best for {k: v for k, v in sorted(d.items(), key=key_getter)}: 12.031082626002899
Best for {k: v for k, v in sorted(d.items(), key=key_lambda)}: 14.22885995300021

Best for dict(sorted(d.items(), key=key_getter)): 11.209122000000207
Best for dict(sorted(d.items(), key=key_lambda)): 13.289728325995384
Best for dict(sorted(d.items())): 14.231471302999125

Best for OrderedDict(sorted(d.items(), key=key_getter)): 16.609151654003654
Best for OrderedDict(sorted(d.items(), key=key_lambda)): 18.52622927199991
Best for OrderedDict(sorted(d.items())): 19.436101284998585
Run Code Online (Sandbox Code Playgroud)

测试代码:

from timeit import repeat

setup_code = """
from operator import itemgetter
from collections import OrderedDict
import random
random.seed(0)
d = {i: chr(i) for i in [random.randint(0, 120) for repeat in range(120)]}
key_getter = itemgetter(0)
key_lambda = lambda item: item[0]
"""

cases = [
    # fast
    '{k: d[k] for k in sorted(d)}',
    '{k: v for k, v in sorted(d.items(), key=key_getter)}',
    '{k: v for k, v in sorted(d.items(), key=key_lambda)}',
    # slower
    'dict(sorted(d.items(), key=key_getter))',
    'dict(sorted(d.items(), key=key_lambda))',
    'dict(sorted(d.items()))',
    # the slowest 
    'OrderedDict(sorted(d.items(), key=key_getter))',
    'OrderedDict(sorted(d.items(), key=key_lambda))',
    'OrderedDict(sorted(d.items()))',
]

for code in cases:
    times = repeat(code, setup=setup_code, repeat=3)
    print(f"Best for {code}: {min(times)}")
Run Code Online (Sandbox Code Playgroud)

  • 我很惊讶 `sorted(d.items())` 比带有 `key` 的版本慢。如果所有较早的值都相等(如果第一个值是字典键,则永远不会发生这种情况),元组的排序仅比较第二个和后面的项目。我想知道为什么这种情况实际上很慢。 (2认同)

Gre*_* E. 11

Python的普通性dicts无法以任何特定顺序提供键/元素.为此,您可以使用模块中的OrderedDict类型collections.请注意,该OrderedDict类型仅保留插入顺序的记录.如果希望后续视图/迭代器每次都按顺序返回元素,则必须在初始化字典之前对条目进行排序.例如:

>>> myDic={10: 'b', 3:'a', 5:'c'}
>>> sorted_list=sorted(myDic.items(), key=lambda x: x[0])
>>> myOrdDic = OrderedDict(sorted_list)
>>> myOrdDic.items()
[(3, 'a'), (5, 'c'), (10, 'b')]
>>> myOrdDic[7] = 'd'
>>> myOrdDic.items()
[(3, 'a'), (5, 'c'), (10, 'b'), (7, 'd')]
Run Code Online (Sandbox Code Playgroud)

如果要为新添加的项维护正确的顺序,则确实需要使用不同的数据结构,例如二叉树/堆.OrderedDict()除非您的数据是完全静态的,否则这种构建排序列表并使用它来初始化新实例的方法效率非常低.

编辑:因此,如果排序数据的对象只是按顺序打印它,以类似python dict对象的格式,类似下面的内容就足够了:

def pprint_dict(d):
    strings = []
    for k in sorted(d.iterkeys()):
        strings.append("%d: '%s'" % (k, d[k]))
    return '{' + ', '.join(strings) + '}'
Run Code Online (Sandbox Code Playgroud)

请注意,此函数不灵活w/r/t键,值对的类型(即,它期望键是整数,相应的值是字符串).如果您需要更多灵活性,请使用类似的功能strings.append("%s: %s" % (repr(k), repr(d[k]))).


Pra*_*ant 6

使用 Python 3.7 我可以这样做:

>>> myDic={10: 'b', 3:'a', 5:'c'}
>>> sortDic = sorted(myDic.items())
>>> print(dict(sortDic))
{3:'a', 5:'c', 10: 'b'}
Run Code Online (Sandbox Code Playgroud)

如果你想要一个元组列表:

>>> myDic={10: 'b', 3:'a', 5:'c'}
>>> sortDic = sorted(myDic.items())
>>> print(sortDic)
[(3, 'a'), (5, 'c'), (10, 'b')]
Run Code Online (Sandbox Code Playgroud)