字典中多个列表列表的子元素的交集
Intersection of subelements of multiple list of lists in dictionary
我有一些列表列表存储在字典中。我想找到子列表的交集(即 intersection of dict[i][j]) for all keys of the dictionary
. )
例如,如果字典改为存储元组集,我可以使用代码:
set.intersection(*[index[key] for key in all_keys])
执行此操作的有效方法是什么?我尝试的一种方法是首先将列表的每个列表转换为一组元组,然后取这些元组的交集,但这相当笨拙。
示例:
假设lists of lists的字典是
dict = {}
dict['A'] = [[1, 'charlie'], [2, 'frankie']]
dict['B'] = [[1, 'charlie'], [2, 'chuck']]
dict['C'] = [[2, 'chuck'], [1, 'charlie']]
那我要return
[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
[item for item in A if item in B+C]
您的用例需要使用 reduce
函数。但是,引用 BDFL's take on reduce、
So now reduce()
. This is actually the one I've always hated most, because, apart from a few examples involving +
or *
, almost every time I see a reduce()
call with a non-trivial function argument, I need to grab pen and paper to diagram what's actually being fed into that function before I understand what the reduce() is supposed to do. So in my mind, the applicability of reduce()
is pretty much limited to associative operators, and in all other cases it's better to write out the accumulation loop explicitly.
那么,你得到的已经是'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(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')])
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
我有一些列表列表存储在字典中。我想找到子列表的交集(即 intersection of dict[i][j]) for all keys of the dictionary
. )
例如,如果字典改为存储元组集,我可以使用代码:
set.intersection(*[index[key] for key in all_keys])
执行此操作的有效方法是什么?我尝试的一种方法是首先将列表的每个列表转换为一组元组,然后取这些元组的交集,但这相当笨拙。
示例:
假设lists of lists的字典是
dict = {}
dict['A'] = [[1, 'charlie'], [2, 'frankie']]
dict['B'] = [[1, 'charlie'], [2, 'chuck']]
dict['C'] = [[2, 'chuck'], [1, 'charlie']]
那我要return
[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
[item for item in A if item in B+C]
您的用例需要使用 reduce
函数。但是,引用 BDFL's take on reduce、
So now
reduce()
. This is actually the one I've always hated most, because, apart from a few examples involving+
or*
, almost every time I see areduce()
call with a non-trivial function argument, I need to grab pen and paper to diagram what's actually being fed into that function before I understand what the reduce() is supposed to do. So in my mind, the applicability ofreduce()
is pretty much limited to associative operators, and in all other cases it's better to write out the accumulation loop explicitly.
那么,你得到的已经是'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(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')])
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