在dict python中对元素进行排序

时间:2017-03-04 12:37:08

标签: python python-2.7 dictionary

我有一个元素字典:

leveldict = {
    (3, 2): (3,), (1, 2, 4): (1, 2), (2, 4, 3): (2, 4), (1, 4): (1,),
    (4,): (), (3, 4, 1): (3, 4), (4, 3): (4,), (2, 3, 1): (2, 3),
    (2, 4): (2,), (1, 2, 3, 4): (1, 2, 3)
}

我想在leveldict中找到键值对的所有序列,其中下一个序列项的键是前一个序列项的值。每个元组中项目的顺序重要。

以下是上面给出的数据的预期输出:

s1 = ((1, 2, 3, 4), (1, 2, 3)), ((2, 3, 1), (2, 3)), ((3, 2), (3,))
s2 = ((1, 2, 4), (1, 2))
s3 = ((2, 4, 3), (2, 4)), ((2, 4), (2,))
s4 = ((3, 4, 1), (3, 4)), ((4, 3), (4,)), ((4,), ())
s5 = ((1, 4), (1,))

注意:leveldict中的元素可以保证形成这样的序列。

1 个答案:

答案 0 :(得分:2)

我们希望忽略每个键元组和值元组中的顺序,因此将它们转换为集合是有意义的。但我们希望将它们用作字典键,因此我们需要使用frozensets,因为普通集不可用。我们可以将它们放入OrderedDict中,以便用最长的密钥更容易地启动每个序列。

from collections import OrderedDict

leveldict = {
    (3, 2): (3,), (1, 2, 4): (1, 2), (2, 4, 3): (2, 4), (1, 4): (1,), 
    (4,): (), (3, 4, 1): (3, 4), (4, 3): (4,), (2, 3, 1): (2, 3), 
    (2, 4): (2,), (1, 2, 3, 4): (1, 2, 3)
}

# Store in an OrderedDict of frozensets, ordered by length
a = [(frozenset(k), frozenset(v)) for k,v in leveldict.items()]
a.sort(key=lambda t:(len(t[0]), len(t[1]))) 
odict = OrderedDict(a)

def unfreeze(k, v):
    return tuple(k), tuple(v)

all_seqs = []
while odict:
    k, v = odict.popitem()
    seq = [unfreeze(k, v)]
    k = v
    while k in odict:
        v = odict.pop(k)
        seq.append(unfreeze(k, v))
        k = v

    all_seqs.append(seq)

# Perform a simple numeric sort on the tuple sequences
all_seqs.sort()
for row in all_seqs:
    print(row) 

<强>输出

[((1, 2, 3, 4), (1, 2, 3)), ((1, 2, 3), (2, 3)), ((2, 3), (3,))]
[((1, 2, 4), (1, 2))]
[((1, 3, 4), (3, 4)), ((3, 4), (4,)), ((4,), ())]
[((1, 4), (1,))]
[((2, 3, 4), (2, 4)), ((2, 4), (2,))]

此处的策略是简单地从odict弹出最长的剩余密钥,并搜索键值链。