Python: 对应于列表字典中的项目的查找键
Python: Lookup keys which correspond to an item in a dictionary of lists
问题陈述
给定一个列表字典,
key_to_list = {
'one': [1, 3, 5, 7],
'two': [2, 4, 6, 8],
'three': [1, 2, 5, 6],
'four': [2, 5, 7, 8]
}
创建从列表元素到它们的键的映射的最佳方法是什么?
list_element_to_keys = {
1: {'one', 'three'},
2: {'two', 'three', 'four'},
3: {'one'},
4: {'two'},
5: {'one', 'three', 'four'},
6: {'two', 'three'},
7: {'one', 'four'},
8: {'two', 'four'}
}
我的解决方案
from collections import defaultdict
list_element_to_keys = defaultdict(set)
for key, value in key_to_list.items():
for item in value:
list_element_to_keys[item].add(key)
想法
我的一个朋友建议可以使用
字典理解,但我一直 运行 问题
因为多个键的列表包含一些相同的项目。
我也认为它们可能是一些 itertools
魔法可以提供帮助,
但我不乐观。
字典理解
在朋友的帮助下,我找到了一个有效的词典理解。
from itertools import chain
list_element_to_keys= { i: set(k for k,v in key_to_list.items() if i in v) for i in set(chain.from_iterable(key_to_list.values())) }
你也可以这样做
d = {}; [d.setdefault(i,[]).append(k) for k,v in key_to_list.items() for i in v]
print d
这导致
{1: ['three', 'one'],
2: ['four', 'three', 'two'],
3: ['one'],
4: ['two'],
5: ['four', 'three', 'one'],
6: ['three', 'two'],
7: ['four', 'one'],
8: ['four', 'two']}
您的解决方案很好,有效,defaultdict
是解决此类问题的明显(好的)选择。
您可以改进的一件事是使用 six.iteritems(key_to_list)
,这将使它在 Python2 上更快一些。
我在单语句嵌套理解中得到它:
- 编译一组值(新键)
- 对于该集合的每个元素,遍历原始键
- 如果原始键在其值列表中有新键,
将该字符串包含在新键的值列表中
代码:
list_element_to_keys = \
{new_key : [old_key for old_key in key_to_list.keys() if new_key in key_to_list[old_key]] \
for new_key in set([item for value_list in key_to_list.values() for item in value_list ])}
print (list_element_to_keys)
输出(添加换行以帮助阅读):
{1: ['one', 'three'], 2: ['two', 'four', 'three'],
3: ['one'], 4: ['two'],
5: ['four', 'one', 'three'], 6: ['two', 'three'],
7: ['four', 'one'], 8: ['two', 'four']}
问题陈述
给定一个列表字典,
key_to_list = {
'one': [1, 3, 5, 7],
'two': [2, 4, 6, 8],
'three': [1, 2, 5, 6],
'four': [2, 5, 7, 8]
}
创建从列表元素到它们的键的映射的最佳方法是什么?
list_element_to_keys = {
1: {'one', 'three'},
2: {'two', 'three', 'four'},
3: {'one'},
4: {'two'},
5: {'one', 'three', 'four'},
6: {'two', 'three'},
7: {'one', 'four'},
8: {'two', 'four'}
}
我的解决方案
from collections import defaultdict
list_element_to_keys = defaultdict(set)
for key, value in key_to_list.items():
for item in value:
list_element_to_keys[item].add(key)
想法
我的一个朋友建议可以使用 字典理解,但我一直 运行 问题 因为多个键的列表包含一些相同的项目。
我也认为它们可能是一些 itertools
魔法可以提供帮助,
但我不乐观。
字典理解
在朋友的帮助下,我找到了一个有效的词典理解。
from itertools import chain
list_element_to_keys= { i: set(k for k,v in key_to_list.items() if i in v) for i in set(chain.from_iterable(key_to_list.values())) }
你也可以这样做
d = {}; [d.setdefault(i,[]).append(k) for k,v in key_to_list.items() for i in v]
print d
这导致
{1: ['three', 'one'],
2: ['four', 'three', 'two'],
3: ['one'],
4: ['two'],
5: ['four', 'three', 'one'],
6: ['three', 'two'],
7: ['four', 'one'],
8: ['four', 'two']}
您的解决方案很好,有效,defaultdict
是解决此类问题的明显(好的)选择。
您可以改进的一件事是使用 six.iteritems(key_to_list)
,这将使它在 Python2 上更快一些。
我在单语句嵌套理解中得到它:
- 编译一组值(新键)
- 对于该集合的每个元素,遍历原始键
- 如果原始键在其值列表中有新键, 将该字符串包含在新键的值列表中
代码:
list_element_to_keys = \
{new_key : [old_key for old_key in key_to_list.keys() if new_key in key_to_list[old_key]] \
for new_key in set([item for value_list in key_to_list.values() for item in value_list ])}
print (list_element_to_keys)
输出(添加换行以帮助阅读):
{1: ['one', 'three'], 2: ['two', 'four', 'three'],
3: ['one'], 4: ['two'],
5: ['four', 'one', 'three'], 6: ['two', 'three'],
7: ['four', 'one'], 8: ['two', 'four']}