查找字典中所有唯一的键对

时间:2018-03-26 12:50:43

标签: python dictionary tuples

如果有字典:

test_dict = { 'a':1,'b':2,'c':3,'d':4}

我想在元组列表中找到成对的键,如:

[('a','b'),('a','c'),('a','d'),('b','c'),('b','d'),('c','d')]

我尝试了以下双重迭代

test_dict = { 'a':1,'b':2,'c':3,'d':4}
result = []
for first_key in test_dict:
    for second_key in test_dict:
        if first_key != second_key:
            pair = (first_key,second_key)
            result.append(pair)

但它产生了以下结果

[('a', 'c'), ('a', 'b'), ('a', 'd'), ('c', 'a'), ('c', 'b'), ('c', 'd'), ('b', 'a'), ('b', 'c'), ('b', 'd'), ('d', 'a'), ('d', 'c'), ('d', 'b')]

对于我的测试用例('a','b')和('b','a')类似,我只想在列表中找到其中一个。我不得不再运行一个循环来从结果中获取唯一对。

那么在Python中有没有有效的方法(最好在2.x中)?我想删除嵌套循环。

更新
我已经检查了可能的flagged duplicate,但是这里没有解决问题。它只是提供不同的组合。我只需要成对的2.对于那个问题,('a','b','c')('a','b','c','d')的元组是有效的,但对我来说它们不是。我希望,这解释了不同之处。

3 个答案:

答案 0 :(得分:9)

听起来像是itertools的工作。

from itertools import combinations
test_dict = {'a':1, 'b':2, 'c':3, 'd':4}
results = list(combinations(test_dict, 2))

[('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]

我应该补充一点,虽然上面的输出恰好是排序的,但这并不能保证。如果订单很重要,您可以改为使用:

results = sorted(combinations(test_dict, 2))

答案 1 :(得分:4)

由于字典键是唯一的,因此该问题等同于查找大小为2的键的所有组合。您可以使用itertools

>>> test_dict = { 'a':1,'b':2,'c':3,'d':4}
>>> import itertools
>>> list(itertools.combinations(test_dict, 2))
[('c', 'a'), ('c', 'd'), ('c', 'b'), ('a', 'd'), ('a', 'b'), ('d', 'b')]

请注意,这些将没有特定的顺序,因为dict对象本质上是无序的。但是如果你想要排序顺序,你可以在之前或之后排序:

>>> list(itertools.combinations(sorted(test_dict), 2))
[('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]
>>>

注意,如果您使用列表之类的序列,则此算法相对简单:

>>> ks = list(test_dict)
>>> for i, a in enumerate(ks):
...     for b in ks[i+1:]: # this is the important bit
...         print(a, b)
...
c a
c d
c b
a d
a b
d b

或者更简洁:

>>> [(a,b) for i, a in enumerate(ks) for b in ks[i+1:]]
[('c', 'a'), ('c', 'd'), ('c', 'b'), ('a', 'd'), ('a', 'b'), ('d', 'b')]
>>>

答案 2 :(得分:3)

itertools.combinations正是您想要的:

from itertools import combinations

test_dict = { 'a':1,'b':2,'c':3,'d':4}
keys = tuple(test_dict)
combs = list(combinations(keys, 2))
print(combs)
# [('a', 'd'), ('a', 'b'), ('a', 'c'), ('d', 'b'), ('d', 'c'), ('b', 'c')]

combs = list(combinations(test_dict, 2))会这样做;迭代字典只是迭代它的键......