簡體   English   中英

Python 2.5字典2鍵排序

[英]Python 2.5 dictionary 2 key sort

我有一個200,000項的字典(鍵是字符串,值是整數)。

什么是打印項目的最佳/最pythonic方式,按降序值排序,然后按升序鍵(即2鍵排序)?

 a={ 'keyC':1, 'keyB':2, 'keyA':1 }
b = a.items()
b.sort( key=lambda a:a[0])
b.sort( key=lambda a:a[1], reverse=True )
print b
>>>[('keyB', 2), ('keyA', 1), ('keyC', 1)]

你不能排序詞典。 您必須對項目列表進行排序。

以前的版本錯了。 如果有數值,則可以按相反順序排序。 這些就是這樣做的。 但這不是一般的。 這只能起作用,因為值是數字。

a = { 'key':1, 'another':2, 'key2':1 }

b= a.items()
b.sort( key=lambda a:(-a[1],a[0]) )
print b

這是一個替代方案,使用顯式函數而不是lambda和cmp而不是key選項。

def valueKeyCmp( a, b ):
    return cmp( (-a[1], a[0]), (-b[1], b[0] ) )

b.sort( cmp= valueKeyCmp )
print b

更通用的解決方案實際上是兩種不同的排序

b.sort( key=lambda a:a[1], reverse=True )
b.sort( key=lambda a:a[0] )
print b
data = { 'keyC':1, 'keyB':2, 'keyA':1 }

for key, value in sorted(data.items(), key=lambda x: (-1*x[1], x[0])):
    print key, value

最詭計多端的方法是更多地了解實際數據 - 特別是你可以擁有的最大值 - 然后像這樣做:

def sortkey((k, v)): 
    return (maxval - v, k)

items = thedict.items()
items.sort(key=sortkey)

但除非你已經知道最大值,否則搜索最大值意味着在dict中循環一個額外的時間(使用max(thedict.itervalues()) ),這可能很昂貴。 或者,S.Lott解決方案的keyfunc版本:

def sortkey((k, v)): 
    return (-v, k)

items = thedict.items()
items.sort(key=sortkey)

不關心類型的替代方案是比較函數:

def sortcmp((ak, av), (bk, bv)):
    # compare values 'in reverse'  
    r = cmp(bv, av)
    if not r:
        # and then keys normally
        r = cmp(ak, bk)
    return r

items = thedict.items()
items.sort(cmp=sortcmp) 

此解決方案實際上適用於您希望在同一個鍵中混合升序和降序排序的任何類型的鍵和值。 如果您重視簡潔,可以將sortcmp寫為:

def sortcmp((ak, av), (bk, bv)):
    return cmp((bk, av), (ak, bv))

你可以使用這樣的東西:

dic = {'aaa':1, 'aab':3, 'aaf':3, 'aac':2, 'aad':2, 'aae':4}

def sort_compare(a, b):
    c = cmp(dic[b], dic[a])
    if c != 0:
        return c
    return cmp(a, b)

for k in sorted(dic.keys(), cmp=sort_compare):
    print k, dic[k]

不知道pythonic是多少:)

以Thomas Wouters和Ricardo Reyes解決方案為基礎:

def combine(*cmps):
    """Sequence comparisons."""
    def comparator(a, b):
        for cmp in cmps:
            result = cmp(a, b):
            if result:
                return result
        return 0
    return comparator

def reverse(cmp):
    """Invert a comparison."""
    def comparator(a, b):
        return cmp(b, a)
    return comparator

def compare_nth(cmp, n):
    """Compare the n'th item from two sequences."""
    def comparator(a, b):
        return cmp(a[n], b[n])
    return comparator

rev_val_key_cmp = combine(
        # compare values, decreasing
        reverse(compare_nth(1, cmp)),

        # compare keys, increasing
        compare_nth(0, cmp)
    )

data = { 'keyC':1, 'keyB':2, 'keyA':1 }

for key, value in sorted(data.items(), cmp=rev_val_key_cmp):
    print key, value
>>> keys = sorted(a, key=lambda k: (-a[k], k))

要么

>>> keys = sorted(a)
>>> keys.sort(key=a.get, reverse=True)

然后

print [(key, a[key]) for key in keys]
[('keyB', 2), ('keyA', 1), ('keyC', 1)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM