如何使用复合键对python字典进行排序和子集?

时间:2015-10-22 15:19:47

标签: python sorting dictionary

我有一个带有复合键(Pri_key,Sec_key)的Python字典和值:

(123, 456): 45
(123, 457): 90
(124, 234): 70
(125, 87): 3
(125, 103): 56
(125, 897): 34

如何在每个" Pri_key"上按降序对值进行排序,并列出相应的" Sec_key"因此? 预期结果:

123: 457 456
124: 234
125: 103 897 83

4 个答案:

答案 0 :(得分:0)

这里的关键是原始排序。之后,您可以在主键上groupby。要构造排序,可以键入(<primary-key>, -<value>)的元组(否定是按降序排列具有相同主键的值):

from itertools import groupby
from operator import itemgetter
sorted_keys = sorted(original_dict, key=lambda key: (key[0], -original_dict[key]))
for primary_key, key_group in groupby(sorted_keys, key=itemgetter(0)):
    print(primary_key, [key[1] for key in key_group])

当然,如果您可以打印键,那么您可以使用它来构建字典(或任何其他数据结构): - )。

这是我终端的演示:

>>> original_dict = {
... (123, 456): 45,
... (123, 457): 90,
... (124, 234): 70,
... (125, 87): 3,
... (125, 103): 56,
... (125, 897): 34
... }
>>>
>>> from itertools import groupby
>>> from operator import itemgetter
>>> sorted_keys = sorted(original_dict, key=lambda key: (key[0], -original_dict[key]))
>>> for primary_key, key_group in groupby(sorted_keys, key=itemgetter(0)):
...     print(primary_key, [key[1] for key in key_group])
... 
(123, [457, 456])
(124, [234])
(125, [103, 897, 87])

答案 1 :(得分:0)

我们需要迭代键,然后使用复合键的第二个值构建另一个字典,作为此新字典指向的列表的一部分。然后我们对新词典的值进行排序。观察。

假设您的原始字典名为d

k = {} # Our new dictionary
for key in d.keys():
    (Pri_key, Sec_key) = key
    try:
        k[Pri_key].append(Sec_key)
    except KeyError:
        k[Pri_key] = [Sec_key] # Make a new list if the new key doesn't exist

# Make a list of sorted keys
keys = [key for key in d.keys()]
keys.sort()
for key in keys:
    list = d[key]
    list.sort()
    print(key + ':' + list)

你有它。

答案 2 :(得分:0)

一衬垫:

sorted((k,sorted(v)) for k,v in functools.reduce(lambda d,k: (d[0],d[0].setdefault(k[0],[]).append(k[1])),d.keys(),({},None))[0].items())

更清晰:

def sort(d):
    new = {k0: [] for k0,_ in d.keys()}
    for k0,k1 in d.keys():
        new[k0].append(k1)
    new_sorted = {k: sorted(v) for k,v in new.items()}
    return sorted(new_sorted.items())

答案 3 :(得分:0)

基于Python 2.7:

>>> d = {(123, 456): 45, (123, 457): 90, (124, 234): 70, (125, 87): 3, (125, 103): 56, (125, 897): 34}
>>> items = d.items()
>>> items.sort(key=lambda e: e[1], reverse=True)
>>> items
[((123, 457), 90), ((124, 234), 70), ((125, 103), 56), ((123, 456), 45), ((125, 897), 34), ((125, 87), 3)]
>>> keys = set(map(lambda e: e[0][0], items))
>>> keys
set([123, 124, 125])
>>> for k in keys:
...     print '%d: %s' % (k, ' '.join([str(e[0][1]) for e in items if e[0][0] == k]))
...
123: 457 456
124: 234
125: 103 897 87