如果有字典:
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')
的元组是有效的,但对我来说它们不是。我希望,这解释了不同之处。
答案 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))
会这样做;迭代字典只是迭代它的键......