![](/img/trans.png)
[英]How to sort a dictionary having string as keys and integer as values in Python
[英]How to sort a dictionary having keys as a string of numbers in Python
我有一本字典:
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 }
就像其他人指出的那樣,字典有自己的排序方式,您不能像對列表一樣對它們進行排序。
我想補充的一件事是,如果您只想按排序順序瀏覽字典的元素,那就是:
for k in sorted(a):
print k, a[k] # or whatever.
如果你更喜歡列表理解(按亞歷克斯):
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
函數快得多。
您不能對一個dict
作為在Python dict
類型本質上是無序的。 您可以做的是在使用sorted()
內置函數之前對項目進行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)
9 年前我發布了一個開始的食譜
字典無法排序——映射沒有排序!
並展示了如何從字典的鍵和值中獲取排序列表。
使用今天的 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
一般來說,如果您從一開始就更准確地指定您的確切要求,您可以更快地獲得更好的答案;-)。
字典是無序的。 你不能像你展示的那樣排序,因為結果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 模式,保留一個取決於鍵函數結果的排序列表。
如果你安裝了我的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']
您還可以做以下事情:
sorted_keys = sorted(list(a.keys()), key = lambda x: (len(x),x))
sorted_dict = {k:a[k] for k in sorted_keys}
最重要的部分是key = lambda x: (len(x),x)
我從這里獲取
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.