Python 字典中多个列表的子元素的交集
我在字典里有很多列表。我想找到字典所有键的子列表的交集(即dict[I][j]的交集) 例如,如果字典存储元组集,我可以使用以下代码:Python 字典中多个列表的子元素的交集,python,list,set,Python,List,Set,我在字典里有很多列表。我想找到字典所有键的子列表的交集(即dict[I][j]的交集) 例如,如果字典存储元组集,我可以使用以下代码: set.intersection(*[index[key] for key in all_keys]) 做这件事的有效方法是什么?我尝试的一种方法是首先将每个列表转换为一组元组,然后取它们的交集,但这相当笨拙 例如: 假设列表字典是 dict = {} dict['A'] = [[1, 'charlie'], [2, 'frankie']] dict['
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
您的用例需要使用
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')])
让我们调用您的列表字典
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(d[k]中x的元组(x))
,这将形成k
中元素的元组集。以d[k]
为例:k='A'
>>> k='A'; set(tuple(x) for x in d[k]) set([(2, 'frankie'), (1, 'charlie')])
这将生成上述步骤中的集合列表。因此:[set(tuple(x)表示d中的x[k])表示d中的k]
>>> [ 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)表示d中的x[k])表示d中的k])
>>>set.intersection( *[ set(tuple(x) for x in d[k]) for k in d ] ) set([(1, 'charlie')])
>>>set.intersection( *[ set(tuple(x) for x in d[k]) for k in d ] )
set([(1, 'charlie')])
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