字典中多个列表列表的子元素的交集

时间:2015-01-26 05:53:02

标签: python list set

我有很多列表存储在字典中。我想找到子列表的交集(即intersection of dict[i][j]) for all keys of the dictionary。)

例如,如果字典存储了元组的集合,我可以使用代码:

set.intersection(*[index[key] for key in all_keys]) 

有效的方法是什么?我试过的一种方法是首先将每个列表列表转换为一组元组,然后取这些列表的交集,但这是相当笨重的。

示例:

假设列表列表是

dict = {} 
dict['A'] = [[1, 'charlie'], [2, 'frankie']] 
dict['B'] = [[1, 'charlie'], [2, 'chuck']]
dict['C'] = [[2, 'chuck'], [1, 'charlie']]

然后我想返回

[1, 'charlie']

(也许作为一个元组,不一定是列表)

编辑:我刚刚找到了一个可行的方法,但它不是'pythonic'

def search(index, search_words): 
    rv = {tuple(t) for t in index[search_words[0]]}
    for word in search_words: 
        rv = rv.intersection({tuple(t) for t in index[word]})
    return rv 

4 个答案:

答案 0 :(得分:2)

让我们调用您的列表d字典:

>>> d = {'A': [[1, 'charlie'], [2, 'frankie']], 'B': [[1, 'charlie'], [2, 'chuck']], 'C': [[2, 'chuck'], [1, 'charlie']]}

我称之为d因为dict是内置的,我们宁愿不覆盖它。

现在,找到路口:

>>> set.intersection( *[ set(tuple(x) for x in d[k]) for k in d ] )
set([(1, 'charlie')])

如何运作

  • set(tuple(x) for x in d[k])

    对于键k,这形成了d[k]中元素元组的集合。以k='A'为例:

    >>> k='A'; set(tuple(x) for x in d[k])
    set([(2, 'frankie'), (1, 'charlie')])
    
  • [ set(tuple(x) for x in d[k]) for k in d ]

    这将显示上述步骤中的集合列表。因此:

    >>> [ set(tuple(x) for x in d[k]) for k in d ]
    [set([(2, 'frankie'), (1, 'charlie')]),
     set([(2, 'chuck'), (1, 'charlie')]),
     set([(2, 'chuck'), (1, 'charlie')])]
    
  • set.intersection( *[ set(tuple(x) for x in d[k]) for k in d ] )

    如上所述收集三组的交集:

    >>>set.intersection( *[ set(tuple(x) for x in d[k]) for k in d ] )
    set([(1, 'charlie')])
    

答案 1 :(得分:1)

[item for item in A if item in B+C]

答案 2 :(得分:1)

您的用例要求使用reduce函数。但是,引用BDFL's take on reduce

  

现在reduce()。这实际上是我一直非常讨厌的那个,因为除了一些涉及+*的示例之外,几乎每次我看到reduce()调用具有非平凡的函数在我理解reduce()应该做什么之前,我需要抓住笔和纸来绘制实际输入到该函数中的内容。所以在我看来,reduce()的适用性几乎仅限于关联运算符,而在所有其他情况下,最好明确地写出累积循环。

所以,你得到的已经是'pythonic'

我会写这样的程序

>>> d = {'A': [[1, 'charlie'], [2, 'frankie']],
... 'B': [[1, 'charlie'], [2, 'chuck']],
... 'C': [[2, 'chuck'], [1, 'charlie']]}
>>> values = (value for value in d.values())
>>> result = {tuple(item) for item in next(values)}
>>> for item in values:
...    result &= frozenset(tuple(items) for items in item)
>>> result
set([(1, 'charlie')])

答案 3 :(得分:1)

from collections import defaultdict    
d = {'A': [[1, 'charlie'], [2, 'frankie']], 'B': [[1, 'charlie'], [2, 'chuck']], 'C': [[2, 'chuck'], [1, 'charlie']]}

frequency = defaultdict(set)
for key, items in d.iteritems():
    for pair in items:
        frequency[tuple(pair)].add(key)
output = [
    pair for pair, occurrances in frequency.iteritems() if len(d) == len(occurrances)
]
print output