排序字典python 3

排序字典python 3,python,dictionary,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]) 但不管怎样,我都不能用这个分类表编一本字典。我该怎么做?谢谢 dict不保持其元素的顺序。您需要的是一个订购信息: 编辑 用法示例: >>> from

我正在研究python 3.2.2。 3个多小时来整理一本字典。 我设法使它成为一个包含2个参数成员的排序列表,但最终无法使它成为一个排序字典

这就是我想的:

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

但不管怎样,我都不能用这个分类表编一本字典。我该怎么做?谢谢

dict
不保持其元素的顺序。您需要的是一个订购信息:

编辑

用法示例:

>>> 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

Python的普通
dicts
不能以任何特定顺序提供键/元素。为此,您可以使用
collections
模块中的
OrderedDict
类型。请注意,
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')]
如果您想为新添加的项目保持适当的顺序,那么您确实需要使用不同的数据结构,例如,二叉树/堆。这种构建排序列表并使用它初始化新的
orderedict()
实例的方法效率低下,除非您的数据是完全静态的

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

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

请注意,该函数对于键、值对的类型(即,它希望键是整数,对应的值是字符串)不灵活。如果您需要更大的灵活性,可以使用类似于
strings.append(“%s:%s”%(repr(k),repr(d[k]))

我喜欢python numpy来处理这类内容!例如:

r=readData()
nsorted = np.lexsort((r.calls, r.slow_requests, r.very_slow_requests, r.stalled_requests))
我有一个将CSV数据导入numpy并按列优先级排序的示例。


凯根

我想你不想要订购的。听起来你更喜欢一个,那是一个按排序顺序维护其键的dict。模块只提供了这样一种数据类型。它是用纯Python、fast-as-C实现编写的,具有100%的覆盖率和数小时的压力

pip的安装非常简单:

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

那么您的代码就是:

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

sortedcontainers模块还与其他流行的实现保持一致。

可能不太好,但我认为:

def order_dic(dic):
    ordered_dic={}
    key_ls=sorted(dic.keys())
    for key in key_ls:
        ordered_dic[key]=dic[key]
    return ordered_dic

这个问题有什么现代的解决办法吗? 我通过以下方式解决了这一问题:

    order = sorted([ job['priority'] for job in self.joblist ])
    sorted_joblist = []
    while order:
        min_priority = min(order)
        for job in self.joblist:
            if job['priority'] == min_priority:
                sorted_joblist += [ job ]
                order.remove(min_priority)
    self.joblist = sorted_joblist
作业列表的格式为: 作业列表=[{'priority':3,'name':'foo',…},{'priority':1,'name':'bar',…}]

  • 基本上,我创建了一个包含所有元素的列表(顺序),我想根据这些元素对dict进行排序
  • 然后我迭代这个列表和dict,当我在dict上找到项目时,我将它发送到一个新的dict,并从“order”中删除该项目

看起来很有效,但我认为有更好的解决方案。

一个现代而快速的解决方案,适用于Python 3.7。也可以在Python 3.6的一些解释器中使用

TLDR

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

sorted_dict = {k: disordered[k] for k in sorted(disordered)}
几乎是公认答案的三倍;如果包括导入,可能会更多

对接受的答案发表评论

接受答案中的示例,而不是仅迭代键-使用
sorted()
key
参数或dict迭代的默认行为-迭代元组
(键,值)
,令人惊讶的是,这比仅比较键和访问列表中的字典元素要慢得多

如何在Python 3.7中按键排序

Python3.7中最大的变化是

  • 您可以使用dict理解生成排序的dict
  • 出于兼容性考虑,使用
    OrderedDict
    可能仍然更可取
  • 不要在没有
    键的情况下使用
    已排序(d.items())
见:

计时结果

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
测试代码:

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)}")

公认的答案确实有效,但不知何故遗漏了一个要点

OP要求提供一本按
键排序的词典,这实际上是不可能的,也不是
orderedict
正在做的事情

OrderedDict以插入顺序维护词典的内容。插入的第一项、第二项等

>>> d = OrderedDict()
>>> d['foo'] = 1
>>> d['bar'] = 2
>>> d
OrderedDict([('foo', 1), ('bar', 2)])

>>> d = OrderedDict()
>>> d['bar'] = 2
>>> d['foo'] = 1
>>> d
OrderedDict([('bar', 2), ('foo', 1)])
从今以后,我将不能真正地在原地对字典进行排序,而只是创建一个插入顺序与键顺序匹配的新字典。这在被接受的答案中是明确的,其中新字典是b

如果您通过容器保持对词典的访问,这可能很重要。如果您打算稍后通过添加或删除项来更改字典,这一点也很重要:它们不会按键顺序插入,而是插入到字典的末尾

>>> d = OrderedDict({'foo': 5, 'bar': 8})
>>> d
OrderedDict([('foo', 5), ('bar', 8)])
>>> d['alpha'] = 2
>>> d
OrderedDict([('foo', 5), ('bar', 8), ('alpha', 2)])
现在,拥有一本按键排序的词典意味着什么?这在通过键访问元素时没有什么区别,只有在迭代项时才有意义。将其作为字典本身的一个属性似乎有些过分。在许多情况下,迭代时对key()进行排序就足够了

这意味着它相当于:

>>> d = {'foo': 5, 'bar': 8}
>>> for k,v in d.iteritems(): print k, v
在按键排序的假设词典上,或:

>>> d = {'foo': 5, 'bar': 8}
>>> for k, v in iter((k, d[k]) for k in sorted(d.keys())): print k, v

当然,通过重载迭代器和维护排序键列表将该行为包装到对象中并不困难。但这可能有些过分。

使用Python 3.7,我可以做到:

>>> myDic={10: 'b', 3:'a', 5:'c'}
>>> sortDic = sorted(myDic.items())
>>> print(dict(sortDic))
{3:'a', 5:'c', 10: 'b'}
如果需要元组列表:

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

字典按定义是无序的,按键排序的主要原因是什么?通过sort方法创建的元组列表可以用于任何可能的需要,但是将元组列表更改回字典将返回随机顺序

>>> myDic
{10: 'b', 3: 'a', 5: 'c'}
>>> sorted(myDic.items())
[(3, 'a'), (5, 'c'), (10, 'b')]
>>> print(dict(myDic.items()))
{10: 'b', 3: 'a', 5: 'c'}

使用
>>> myDic
{10: 'b', 3: 'a', 5: 'c'}
>>> sorted(myDic.items())
[(3, 'a'), (5, 'c'), (10, 'b')]
>>> print(dict(myDic.items()))
{10: 'b', 3: 'a', 5: 'c'}
a = {'b':'foo', 'c':'bar', 'e': 'baz'}
a = {f:a[f] for f in sorted(a, key=a.__getitem__)}
def sor_dic_key(diction):
    lista = []
    diction2 = {}
    for x in diction:
        lista.append([x, diction[x]])
    lista.sort(key=lambda x: x[0])
    for l in lista:
        diction2[l[0]] = l[1]
    return diction2