【问题标题】:Sorting dict items by key, beyond alphanumeric sorting按键排序 dict 项目,超出字母数字排序
【发布时间】:2017-02-26 13:31:36
【问题描述】:

我已经写了这段代码:

n=5
dizN={}
for q in range(0,n+1):
    h=n-q
    dizN['a'+str(q)+'p'+str(h)]=0

创建这样的字典:

dizN

Out[120]: {'a0p5': 0, 'a1p4': 0, 'a2p3': 0, 'a3p2': 0, 'a4p1': 0, 'a5p0': 0}

请注意,“n”是我的代码的基本参数。如您所见,dict 键字符串中存在的整数总和始终为 =n(在本例中为 =5,其中 n=5)。

对我来说重要的是(对于我的程序中更困难的目的),对于每个人都可以选择的 n,dict 以这种方式排序:

{'a0p(n)': 0, 'a1p(n-1)': 0, ....., 'a(n-1)p1': 0, 'a(n)p0': 0}

我的代码没问题,但仅适用于 n=10,会发生以下情况:(n=12) dizN:

Out[121]: 
  {'a0p12': 0,
   'a10p2': 0,
   'a11p1': 0,
   'a12p0': 0,
   'a1p11': 0,
   'a2p10': 0,
   'a3p9': 0,
   'a4p8': 0,
   'a5p7': 0,
   'a6p6': 0,
   'a7p5': 0,
   'a8p4': 0,
   'a9p3': 0}

如您所见,解释器遵循字母数字排序;

任何人都知道是否有办法获得以这种方式排序的相同字典:

{'a0p12': 0,
 'a1p11': 0,
 'a2p10': 0,
 'a3p9': 0,
 'a4p8': 0,
 'a5p7': 0,
 'a6p6': 0,
 'a7p5': 0,
 'a8p4': 0,
 'a9p3': 0,
 'a10p2': 0,
 'a11p1': 0,
 'a12p0': 0}

?

我知道字典基本上是不可排序的,但我希望有人知道一些技巧来达到我的目的:)

非常感谢!

【问题讨论】:

  • 你写了很多次关于排序字典,但是Python的字典不能排序。也许你应该看看OrderedDict
  • 字典的全部意义在于它没有排序。这是一个哈希表。
  • 我想遵循的排序标准是“简单地”按字典键字符串中的第一个整数,被认为是一个整数(而不是字符串)升序。或者,为了更好地解释,在作为我的 dict 键的字符串中字母 'a' 后面的整数:'a(integer)p(integer)'。

标签: python sorting dictionary tuples


【解决方案1】:

dictsunordered 的,因此要获得订单,您必须对项目进行排序并使用 OrderedDict 来维护排序命令。要获得您想要的顺序,您可以从整数组创建元组,以便按字典顺序排序为整数:

from itertools import groupby
from collections import OrderedDict
d = {'a0p12': 0, 'a10p2': 0, 'a11p1': 0, 'a12p0': 0, 'a1p11': 0, 'a2p10': 0,
     'a3p9': 0, 'a4p8': 0, 'a5p7': 0, 'a6p6': 0, 'a7p5': 0, 'a8p4': 0, 'a9p3': 0}

def key_func(x):
    """'a0p12' -> (0, 12)"""
    return tuple(int("".join(v)) for k,v in groupby(x[0], key=str.isdigit) if k)
od = OrderedDict(sorted(d.items(), key=key_func))

print(od)

这会给你:

OrderedDict([('a0p12', 0), ('a1p11', 0), ('a2p10', 0), ('a3p9', 0), 
('a4p8', 0), ('a5p7', 0), ('a6p6', 0), ('a7p5', 0), ('a8p4', 0), 
('a9p3', 0), ('a10p2', 0), ('a11p1', 0), ('a12p0', 0)])

您还可以使用 regex 来查找数字组:

from collections import OrderedDict
import re

d = {'a0p12': 0, 'a10p2': 0, 'a11p1': 0, 'a12p0': 0, 'a1p11': 0, 'a2p10': 0,
     'a3p9': 0, 'a4p8': 0, 'a5p7': 0, 'a6p6': 0, 'a7p5': 0, 'a8p4': 0, 'a9p3': 0}



def key_func(x,patt=re.compile("\d+")):
    """'a0p12' -> (0, 12)"""
    return tuple(map(int, patt.findall(x[0])))

od = OrderedDict(sorted(d.items(), key=key_func))

print(od)

【讨论】:

  • 非常感谢帕德莱克!我将在我的程序中尝试这个漂亮的解决方案,然后我将针对涉及这种奇怪排序需求的最大问题提出另一个问题! :)
  • 不用担心,字母总是相同且顺序相同,还是需要考虑?
  • 字母没有这样的问题。 dict 键形式始终为:
  • 'a'(integer)'p'(integer) 再见!
  • 再次感谢,当然,第二种解决方案也很有效。
猜你喜欢
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-29
  • 1970-01-01
相关资源
最近更新 更多