我有一本字典:
a = {'100':12,'6':5,'88':3,'test':34, '67':7,'1':64 }
我想对关键字这个字典进行排序,看起来像是:
a = {'1':64,'6':5,'67':7,'88':3, '100':12,'test':34 }
答案 0 :(得分:12)
正如其他人所指出的那样,词典有自己的排序,你不能像对待列表一样对它们进行排序。
我想补充的一点是,如果您只想按排序顺序浏览字典的元素,那就是:
for k in sorted(a):
print k, a[k] # or whatever.
如果你更喜欢列表理解(每个Alex):
sortedlist = [(k, a[k]) for k in sorted(a)]
我想指出,Alex使用key=int
无法使用您的示例,因为您的一个密钥是'test'
。如果你真的希望他的数字在非数字之前排序,你将不得不传递cmp
函数:
def _compare_keys(x, y):
try:
x = int(x)
except ValueError:
xint = False
else:
xint = True
try:
y = int(y)
except ValueError:
if xint:
return -1
return cmp(x.lower(), y.lower())
# or cmp(x, y) if you want case sensitivity.
else:
if xint:
return cmp(x, y)
return 1
for k in sorted(a, cmp=_compare_keys):
print k, a[k] # or whatever.
或者你可能对你的密钥有足够的了解,可以编写一个函数将它们转换成一个正确排序的字符串(或其他对象):
# Won't work for integers with more than this many digits, or negative integers.
MAX_DIGITS = 10
def _keyify(x):
try:
xi = int(x)
except ValueError:
return 'S{0}'.format(x)
else:
return 'I{0:0{1}}'.format(xi, MAX_DIGITS)
for k in sorted(a, key=_keyify):
print k, a[k] # or whatever.
这比使用cmp
函数要快得多。
答案 1 :(得分:6)
您无法在Python中对dict
进行排序,因为dict
类型本质上是无序的。您可以做的是在使用sorted()
内置函数使用之前对项目进行排序。您还需要一个辅助函数来区分数字键和字符串键:
def get_key(key):
try:
return int(key)
except ValueError:
return key
a = {'100':12,'6':5,'88':3,'test':34, '67':7,'1':64 }
print sorted(a.items(), key=lambda t: get_key(t[0]))
然而,在Python 3.1(和2.7)中,collections
模块包含collections.OrderedDict
类型,可用于实现您想要的效果,如下所示:
def get_key(key):
try:
return int(key)
except ValueError:
return key
a = {'100':12,'6':5,'88':3,'test':34, '67':7,'1':64 }
b = collections.OrderedDict(sorted(a.items(), key=lambda t: get_key(t[0])))
print(b)
答案 2 :(得分:5)
9年前,我发布了启动<{em>
的recipe无法对字典进行排序 - a 映射没有排序!
并显示如何从字典的键和值中排序列表。
使用今天的Python,以及你表达的加上隐含的规范,我建议:
import sys
def asint(s):
try: return int(s), ''
except ValueError: return sys.maxint, s
sortedlist = [(k, a[k]) for k in sorted(a, key=asint)]
key=asint
告诉sorted
将这些字符串键作为整数处理,以便进行排序。 '2'
在'1'
和'12'
之间进行排序,而不是在它们之间进行排序 - 这就是您看起来需要的内容,以及所有非全数字键排序
全数字的。如果你还需要处理表示大于sys.maxint的整数的全数字键字符串,那它有点棘手,但仍然可行:
class Infinity(object):
def __cmp__(self, other): return 0 if self is other else 1
infinite = Infinity()
def asint(s):
try: return int(s), ''
except ValueError: return infinite, s
一般情况下,如果从一开始就更准确地指定确切的要求,就可以更快地得到更好的答案。 - )。
答案 3 :(得分:4)
字典无序。你不能像你所显示的那样对它进行排序,因为结果a
是一个dict,并且dicts没有顺序。
如果你想要一个列表按顺序排列的键列表,你可以使用像
这样的代码>>> def my_key(dict_key):
... try:
... return int(dict_key)
... except ValueError:
... return dict_key
...
>>> sorted(a, key=my_key)
['1', '6', '67', '88', '100', 'test']
这依赖于愚蠢的Python行为,str
的实例总是大于int
的实例。 (行为在Python 3中得到修复。)在最佳设计中,你的dict的键是你可以比较的东西,你不会混合表示数字的字符串和表示单词的字符串。
如果要将密钥保持在按顺序排列的顺序,可以使用bisect
模块或实现依赖于树数据结构的映射。 bisect
模块不接受类似排序内容的key
参数,因为这可能效率低下;如果选择使用bisect
,则使用decorate-use-undecorate模式,保留一个取决于键函数结果的排序列表。
答案 4 :(得分:2)
如果您安装了我的blist软件包,则其中包含sorteddict
类型。那么你可以简单地说:
from blist import sorteddict
def my_key(dict_key):
try:
return int(dict_key)
except ValueError:
return dict_key
a = {'100':12,'6':5,'88':3,'test':34, '67':7,'1':64 }
print sorteddict(my_key, **a).keys()
输出:
['1', '6', '67', '88', '100', 'test']