查找具有公共元素的元组

查找具有公共元素的元组

问题描述:

假设我有一组带有人名的元组.我想找到所有姓氏相同的人,排除与其他人不同姓氏的人:

Suppose I have a set of tuples with people's names. I want to find everyone who shares the same last name, excluding people who don't share their last name with anyone else:

# input
names = set([('John', 'Lee'), ('Mary', 'Miller'), ('Paul', 'Ryan'), 
             ('Bob', 'Ryan'), ('Tina', 'Lee'), ('Bob', 'Smith')])

# expected output
{'Lee': ['Tina', 'John'], 'Ryan': ['Bob', 'Paul']} # or similar

这是我正在使用的

def find_family(names):
    result = {}

    try:
        while True:
            name = names.pop()
            if name[1] in result:
                result[name[1]].append(name[0])
            else:
                result[name[1]] = [name[0]]
    except KeyError:
        pass

    return dict(filter(lambda x: len(x[1]) > 1, result.items()))

这看起来丑陋且效率低下.有没有更好的办法?

This looks ugly and inefficient. Is there a better way?

defaultdict 可以用来简化代码:

defaultdict can be used to simplify the code:

from collections import defaultdict

def find_family(names):
    d = defaultdict(list)
    for fn, ln in names:
        d[ln].append(fn)
    return dict((k,v) for (k,v) in d.items() if len(v)>1)

names = set([('John', 'Lee'), ('Mary', 'Miller'), ('Paul', 'Ryan'), 
             ('Bob', 'Ryan'), ('Tina', 'Lee'), ('Bob', 'Smith')])
print find_family(names)

打印:

{'Lee': ['Tina', 'John'], 'Ryan': ['Bob', 'Paul']}