Reputation: 608
I have the below code to find and print all symmetric pairs from given input.
'''
Given a list of number pairs.
If pair(i,j) exist, and pair(j,i) exist report all such pairs.
'''
def find_all_symmetric_pairs(inp_dic):
for key in inp_dic:
val = inp_dic[key]
if inp_dic[val] == key:
return key,val
return -1,-1
inp_dic = {'1':'3','2':'6','3':'5','7':'4','5':'3','8':'7'}
print type(inp_dic)
key,value = find_all_symmetric_pairs(inp_dic)
print "key:"+str(key)
print "value:"+str(value)
Output:
key:3
value:5
But if I change the input to
inp_dic = {(1,3),(2,6),(3,5),(7,4),(5,3),(8,7)}
or
inp_dic = {{1,3},{2,6},{3,5},{7,4},{5,3},{8,7}}
I have difficulty iterating. How do I achieve the same?
Upvotes: 1
Views: 2134
Reputation: 11971
This seems like a useful solution:
d = {'1':'3','2':'6','3':'5','7':'4','5':'3','8':'7'}
pairs = [(key, value) for key, value in d.items()]
answer = [(x, y) for (x, y) in pairs if (y, x) in pairs]
print(answer)
Output
[('3', '5'), ('5', '3')]
It may also be faster if we make pairs
a set
instead of a list
:
d = {'1':'3','2':'6','3':'5','7':'4','5':'3','8':'7'}
pairs = {(key, value) for key, value in d.items()}
answer = [(x, y) for (x, y) in pairs if (y, x) in pairs]
print(answer)
Output
[('3', '5'), ('5', '3')]
Upvotes: 4
Reputation: 608
I fixed the issue the following way. Hence answering my own question.
def find_all_symmetric_pairs(inp_dic):
for key in inp_dic.iterkeys():
val = inp_dic.get(key)
if inp_dic.get(val) == key:
yield key,val
return
inp_dic = [(1,3),(2,6),(3,5),(7,4),(5,3),(8,7)]
inp_dic = dict(inp_dic)
for key, val in find_all_symmetric_pairs(inp_dic):
print "key: " + str(key)
print "value: " + str(val)
Upvotes: 1
Reputation: 114548
Your function find_all_symmetric_pairs
actually only finds one symmetric pair. You can either make it into a generator function that will really iterate over all the keys:
def find_all_symmetric_pairs(inp_dic):
for key in inp_dic:
val = inp_dic[key]
if inp_dic[val] == key:
yield key,val
return -1,-1
for key, val in find_all_symmetric_pairs(inp_dic):
print "key: " + str(key)
print "value: " + str(val)
or you can do the generation manually by appending to a list:
def find_all_symmetric_pairs(inp_dic):
keys = []
vals = []
for key in inp_dic:
val = inp_dic[key]
if inp_dic[val] == key:
keys.append(key)
vals.append(val)
return keys, vals
for key, val in zip(*find_all_symmetric_pairs(inp_dic)):
print "key: " + str(key)
print "value: " + str(val)
Keep in mind that inp_dic = {(1,3),(2,6),(3,5),(7,4),(5,3),(8,7)}
creates a set of tuples, while inp_dic = {{1,3},{2,6},{3,5},{7,4},{5,3},{8,7}}
attempts to create a set of sets, which is illegal because sets are mutable and therefore unhashable. The first case will require more complex iteration than just using a dictionary because you will have to search all of the tuples for a matching key or value. To get around this, you can easily convert to a dictionary using a dictionary comprehension:
inp_dic = {(1,3),(2,6),(3,5),(7,4),(5,3),(8,7)}
inp_dic = {x[0]: x[1] for x in inp_dic}
Upvotes: 1
Reputation: 1898
with a generator https://wiki.python.org/moin/Generators
def find_all_symmetric_pairs(inp_dic):
for key in inp_dic:
val = inp_dic[key]
if inp_dic[val] == key:
yield key,val
Upvotes: 2
Reputation: 51907
Well, for one you're changing the type of inp_dic
to a set of tuples or a set of sets - which apparently shouldn't even work, since sets are unhashable:
>>> input_set = {{1,3}, {3,3}}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
But you can iterate over the set of tuples like this:
input_set = {(1,3), (42,23)}
for a, b in input_set:
print(a, b)
Upvotes: 1