字符串我有一個字典詞典:如何排序具有鍵作爲數字在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 }
字符串我有一個字典詞典:如何排序具有鍵作爲數字在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)]
我想指出的是,亞歷克斯的使用key=int
不會與你的榜樣工作,因爲你的關鍵之一是'test'
。如果你真的想他非NUMERICS之前排序號碼,你就必須在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
功能快得多。
字典無序。你不能排序,因爲結果a
是一個字典,並且字典沒有順序。
如果你想,說,名單中排序順序的關鍵字的列表,你可以使用如下代碼
>>> 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中得到了解決。)在優化設計中,您的詞典的關鍵字將是您可以比較理智的事物,並且您不會在代表數字和字符串的字符串中混用字符。
如果要按照始終排序的順序保存密鑰,則可以使用bisect
模塊或實現依賴樹數據結構的映射。 bisect
模塊不接受像排序內容這樣的參數,因爲這可能效率低下;如果您選擇使用bisect
,則會使用裝飾使用undecorate模式,並保留一個取決於鍵函數結果的排序列表。
請注意,使用平分維護排序列表需要O(n ** 2)時間。對分將找到每個項目以O(log n)時間插入的正確位置,但由於Python列表類似數組的性質,插入仍然每個項目需要O(n)個時間。 – 2010-03-30 20:11:15
@Daniel Strutzbach,這取決於你的意思是「維護」;根據使用情況,您通常可以避免使用insort構建排序列表的二次方行爲。使用列表和「bisect」當然不會爲插入操作提供理想的性能。如果這些操作很重要,那麼最好使用「或實現依賴於樹數據結構的映射」。既然你已經爲我們做了這些,我提高了你的帖子,它引用了你的'sorteddict'實現。 – 2010-03-30 20:23:24
您不能在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)
這不會得到OP所需的訂單。 – 2010-03-30 19:32:29
嗨Mawushe, 首先讓我感謝你的建議。但是,給定的代碼仍然不能提供所需的解決方案。 – Joseph 2010-03-30 19:37:55
你們兩個都是正確的紳士我已經更新了答案,按鍵排序並考慮到鍵的字符串性質。 – 2010-03-30 19:49:31
9年前我張貼recipe是開始
字典無法排序 - 一個 映射沒有排序!
,並演示瞭如何獲取排序列表了字典的鍵和值。
在今天的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
在一般情況下,你可以,如果你從一開始就;-)更精確地指定您的具體要求得到更好的答案更快。
對於指定的輸入OP,這會失敗,因爲當遇到'test''時'int'會引發'ValueError'。 – 2010-03-30 19:33:05
@Mike,對 - 讓我解決這個問題。 – 2010-03-30 19:34:37
嗨亞歷克斯, 謝謝你的善意幫助和建議。有效...! – Joseph 2010-03-30 19:40:26
如果您安裝我的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']
把7個空格縮進';)',如果你需要一個總是排序的映射,這是一個很好的解決方案。 – 2010-03-30 20:05:32
我不太喜歡這樣的解決方案。 '_keyify'是不必要的僵化,我不認爲像其他一些解決方案一樣乾淨,你的'_compare_keys'使用'cmp',這通常是一個不好的跡象。 (對'try' /'''''try''''''''''''''''''''''''''''''''''''''''''')儘可能小的''''''''''''''''''''''格式(xi,MAX_DIGITS)'' 'else'塊。) – 2010-03-30 20:16:23
不,這些解決方案沒有進行優化,它們只是作爲示例或起點。 (如果不知道實際的關鍵域是什麼,很難提出更好的解決方案。)我喜歡你的解決方案,除了它在Python 3中中斷的地方。我最初編寫了帶有兩行「try」塊的'_compare_keys',但是這是兩倍長。使用'try'塊來控制執行流程消除了對'yint'布爾值的需要。 – 2010-03-31 12:29:06
我假設你的意思是使用'cmp'參數,而不是函數,是一個「不好的符號」,是的它,但它是由未完全定義的關鍵域引發的。這就是爲什麼我跟着'_keyify'解決方案。更好的辦法是爲鍵創建一個新的類,它可以接受字符串輸入並正確排序,並將其用作字典的鍵,但是我不知道ben是否對輸入字典有很大的控制。而且,是的,我忘了「其他」塊;最近C++太多了。固定。 – 2010-03-31 12:33:03