2016-01-14 141 views
1

对称对我有下面的代码,以查找和打印从给定输入的所有对称对。查找蟒蛇

''' 
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) 

输出:

key:3 
value:5 

但是,如果我改变输入到

inp_dic = {(1,3),(2,6),(3,5),(7,4),(5,3),(8,7)} 

inp_dic = {{1,3},{2,6},{3,5},{7,4},{5,3},{8,7}} 

我有困难的迭代。我如何实现相同?

+1

显示你的错误。它几乎告诉你到底是什么问题。 –

+1

'or'后面的输入是无效的Python。这基本上是一组集合,这是不可能的(不可哈),没有意义(重复过滤出来)。 –

回答

3

这似乎是一个有用的解决方案:

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) 

输出

[('3', '5'), ('5', '3')] 

它可能也比较快,如果我们做的pairs一个set代替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) 

输出

[('3', '5'), ('5', '3')] 
+0

谢谢!非常优雅的解决方案 – KurinchiMalar

+0

通过将'pairs'设置为'set'可能会更快一些,并且如果(y,x)对(x,y)成对使用'[(x,y)成对]' –

+0

@tobias_k感谢您的提示 - 我已更新我的回答以反映您的评论。 – gtlambert

1

那么,对于一个你改变的inp_dic类型的元组或一组套 - 这显然是不应该甚至工作,因为集unhashable:

>>> input_set = {{1,3}, {3,3}} 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'set' 

,但你可以遍历这样的元组的集合:

input_set = {(1,3), (42,23)} 
for a, b in input_set: 
    print(a, b) 
2

与发电机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 
+0

这并没有解决我仍然得到的问题,“TypeError:不可能的类型:'设置'” – KurinchiMalar

+1

好吧,你必须学习什么是一个发电机是 – rbp

+0

@KurinchiMalar你不能放集合,因为它们不可散列。你可以使用frozensets,但这也行不通,因为集合没有顺序,所以{1,3}和{3,1}是一样的,因为集合没有重复,第二个会在之前被抛出你可以运行你的方法。 –

1

您的功能find_all_symmetric_pairs实际上只找到一个对称对。您可以使它成为一台发电机的功能,将真正遍历所有的按键:

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) 

,或者你可以手动追加到一个列表做代:

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) 

记住inp_dic = {(1,3),(2,6),(3,5),(7,4),(5,3),(8,7)}创建一个元组,而inp_dic = {{1,3},{2,6},{3,5},{7,4},{5,3},{8,7}}试图创建一套套的,因为集是可变的,因此unhashable这是违法的。第一种情况将需要更复杂的迭代,而不仅仅是使用字典,因为您必须搜索所有元组以查找匹配的键或值。为了解决这个问题,你可以使用字典理解很容易地转换到词典:

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} 
+0

...它的工作原理!感谢您的精彩解释。 – KurinchiMalar

+0

@KurinchiMalar,你知道你可以在你找到更好的答案时改变选定的答案。只是说... –

0

我解决了该问题下面的方式。因此回答我自己的问题。

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)