每个键有多个值的列表到字典转换?
Posted
技术标签:
【中文标题】每个键有多个值的列表到字典转换?【英文标题】:list to dictionary conversion with multiple values per key? 【发布时间】:2011-07-19 16:36:26 【问题描述】:我有一个包含键/值对的 Python 列表:
l = [[1, 'A'], [1, 'B'], [2, 'C']]
我想将列表转换为字典,其中每个键的多个值将聚合成一个元组:
1: ('A', 'B'), 2: ('C',)
迭代解法很简单:
l = [[1, 'A'], [1, 'B'], [2, 'C']]
d =
for pair in l:
if pair[0] in d:
d[pair[0]] = d[pair[0]] + tuple(pair[1])
else:
d[pair[0]] = tuple(pair[1])
print(d)
1: ('A', 'B'), 2: ('C',)
对于这项任务,是否有更优雅的 Pythonic 解决方案?
【问题讨论】:
【参考方案1】:from collections import defaultdict
d1 = defaultdict(list)
for k, v in l:
d1[k].append(v)
d = dict((k, tuple(v)) for k, v in d1.items())
d
现在包含 1: ('A', 'B'), 2: ('C',)
d1
是一个以列表为值的临时默认字典,将在最后一行转换为元组。这样,您将追加到列表,而不是在主循环中重新创建元组。
【讨论】:
【参考方案2】:使用列表而不是元组作为字典值:
l = [[1, 'A'], [1, 'B'], [2, 'C']]
d =
for key, val in l:
d.setdefault(key, []).append(val)
print(d)
使用普通字典通常比 defaultdict
更可取,特别是如果您只构建一次,然后在以后的代码中继续读取它:
首先,普通字典的构建和访问速度更快。
其次,更重要的是,如果您尝试访问一个不存在的密钥,而不是静默创建该密钥,那么后面的读取操作将出错。普通字典可让您明确说明何时要创建键值对,而 defaultdict
始终在任何类型的访问中隐式创建它们。
【讨论】:
使用d.setdefault(key,[]).append(val)
和d.get(key,[]).append(val)
有什么区别/优势?
setdefault()
的优点是使用 .get()
不起作用:\
@jtlz2 .get()
仅从字典中检索值。如果给定键没有条目,get 将愉快地返回新列表并允许将值附加到该列表,但不会更新字典以实际包含新列表,因此新列表将在之后被垃圾回收追加新值。【参考方案3】:
这种方法比较高效,也比较紧凑:
reduce(lambda x, (k,v): x[k].append(v) or x, l, defaultdict(list))
在 Python3 中,这变为(明确导出):
dict(functools.reduce(lambda x, d: x[d[0]].append(d[1]) or x, l, collections.defaultdict(list)))
请注意,reduce 已移至 functools,并且 lambda 不再接受元组。此版本在 2.6 和 2.7 中仍然有效。
【讨论】:
不错,但在 python 3.5 或更高版本中无效【参考方案4】:输入列表中的键是否已经排序?如果是这种情况,您就有了一个实用的解决方案:
import itertools
lst = [(1, 'A'), (1, 'B'), (2, 'C')]
dct = dict((key, tuple(v for (k, v) in pairs))
for (key, pairs) in itertools.groupby(lst, lambda pair: pair[0]))
print dct
# 1: ('A', 'B'), 2: ('C',)
【讨论】:
如果你import operator
,你可以写itertools.groupby(sorted(lst), operator.itemgetter(0))
【参考方案5】:
我创建了一个值列表,如下所示:
performance_data = driver.execute_script('return window.performance.getEntries()')
然后我必须将数据(名称和持续时间)存储在具有多个值的字典中:
dictionary =
for performance_data in range(3):
driver.get(self.base_url)
performance_data = driver.execute_script('return window.performance.getEntries()')
for result in performance_data:
key=result['name']
val=result['duration']
dictionary.setdefault(key, []).append(val)
print(dictionary)
【讨论】:
【参考方案6】:我的数据在 Pandas.DataFrame 中
myDict = dict()
for idin set(data['id'].values):
temp = data[data['id'] == id]
myDict[id] = temp['IP_addr'].to_list()
myDict
给我一个包含键、ID、映射到 >= 1 IP_addr 的字典。第一个 IP_addr 是 Guaranteed。即使temp['IP_addr'].to_list() == []
'fooboo_NaN': ['1.1.1.1', '8.8.8.8']
【讨论】:
以上是关于每个键有多个值的列表到字典转换?的主要内容,如果未能解决你的问题,请参考以下文章