问题
If there's a dictionary:
test_dict = { 'a':1,'b':2,'c':3,'d':4}
I want to find pairs of keys in list of tuples like:
[('a','b'),('a','c'),('a','d'),('b','c'),('b','d'),('c','d')]
I tried with the following double iteration
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)
But it's generating the following result
[('a', 'c'), ('a', 'b'), ('a', 'd'), ('c', 'a'), ('c', 'b'), ('c', 'd'), ('b', 'a'), ('b', 'c'), ('b', 'd'), ('d', 'a'), ('d', 'c'), ('d', 'b')]
For my test case ('a','b') and ('b','a') are similar and I just want one of them in the list. I had to run one more loop for getting the unique pairs from the result.
So is there any efficient way to do it in Python (preferably in 2.x)? I want to remove nested loops.
Update:
I have checked with the possible flagged duplicate, but it's not solving the problem here. It's just providing different combination. I just need the pairs of 2. For that question a tuple of ('a','b','c')
and ('a','b','c','d')
are valid, but for me they are not. I hope, this explains the difference.
回答1:
Sounds like a job for 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')]
I should add that although the output above happens to be sorted, this is not guaranteed. If order is important, you can instead use:
results = sorted(combinations(test_dict, 2))
回答2:
Since dictionary keys are unique, this problem becomes equivalent of finding all combinations of the keys of size 2. You can just use itertools
for that:
>>> 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')]
Note, these will come in no particular order, since dict
objects are inherently unordered. But you can sort before or after, if you want sorted order:
>>> list(itertools.combinations(sorted(test_dict), 2))
[('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]
>>>
Note, this algorithm is relatively simple if you are working with sequences like a list:
>>> 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
Or more succinctly:
>>> [(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')]
>>>
回答3:
itertools.combinations does just what you want:
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))
would just do; iterating over a dictionary is just iterating over its keys...
来源:https://stackoverflow.com/questions/49491914/find-all-unique-pairs-of-keys-of-a-dictionary