Python 合并两个列表并创建一个新词典
我找不到一个好办法来做这件事。假设我有两个列表(列表中有具有给定属性的对象)。我需要创建一个包含合并属性的新词典/列表Python 合并两个列表并创建一个新词典,python,list,dictionary,Python,List,Dictionary,我找不到一个好办法来做这件事。假设我有两个列表(列表中有具有给定属性的对象)。我需要创建一个包含合并属性的新词典/列表 listA = [ { "alpha": "some value", "time": "datetime", }, ... ] listB = [ { "beta": "some val", "gamma": "some val", "time": "datetime" }, ... ] 结果如下(应根据“时间
listA = [
{
"alpha": "some value",
"time": "datetime",
},
...
]
listB = [
{
"beta": "some val",
"gamma": "some val",
"time": "datetime"
},
...
]
结果如下(应根据“时间”属性合并)
如何以python的方式实现这一点
比如说,
listA = [
{
"time": "Jan 1",
"alpha": "one"
},
{
"time": "Jan 3",
"alpha": "three"
}
]
listB = [
{
"beta": "one-one",
"gamma": "one-two",
"time": "Jan 1"
},
{
"beta": "two-one",
"gamma": "two-two",
"time": "Jan 2"
},
]
result = {
"Jan 1": {
"alpha": "one",
"beta": "one-one",
"gamma": "one-two",
},
"Jan 2": {
"beta": "two-one",
"gamma": "two-two",
},
"Jan 3": {
"alpha": "three"
}
}
这段代码可能是一个良好的开端:
listA = [
{
"time": "Jan 1",
"alpha": "one"
},
{
"time": "Jan 3",
"alpha": "three"
}
]
listB = [
{
"beta": "one-one",
"gamma": "one-two",
"time": "Jan 1"
},
{
"beta": "two-one",
"gamma": "two-two",
"time": "Jan 2"
},
]
result = {}
# We consider every element of A and B one by one
for elem in listA + listB:
key = elem["time"]
# If that is the first time we encounter that key, we create a new empty dict in result
if not result.get(key, None):
result[key] = {}
# We copy the content of the elem in listA or listB into the right dictionnary in result.
for dictKey in elem.keys():
# We don't want to copy the time
if dictKey == "time":
continue
result[key][dictKey] = elem[dictKey]
print(result)
使用列表理解
因为您正在搜索一个不使用for循环的替代方案,所以这里有一个使用的实现,它会产生一个两行程序。我不确定这是否比for循环更直观:
output = {}
[output.setdefault(item["time"],{}).update({key: value})
for key, value in item.items()
if key != "time"
for item in (listA + listB)]
对我来说,这只是一个更复杂的循环方式。。。
文件
使用classic for循环
使用示例中给出的listA
和listB
:
combined = listA + listB
merged = {}
for item in combined:
time = item["time"]
# setdefault only acts if the key is not found, initiate a dict then
merged.setdefault(time, {})
for key, value in item.items():
if key != "time":
merged[time].update({key: value})
print merged
输出:
{'Jan 2': {'beta': 'two-one', 'gamma': 'two-two'}, 'Jan 3': {'alpha': 'three'}, 'Jan 1': {'alpha': 'one', 'beta': 'one-one', 'gamma': 'one-two'}}
另一个答案可能更简洁,因为它避免了有利于dict方法的条件测试,并且只使用了一个缩进级别:
d={}
for e in listA:
t = e["time"]
d.setdefault(t, {}).update(**e)
for e in listB:
t = e["time"]
d.setdefault(t, {}).update(**e)
# get rid of "time" keys, if important to do so
for e in d.values():
del e["time"]
d.setdefault(t,{})
如果d
中还没有键t
,则将d[t]
创建为空dict,并返回d[t]
。然后,.update(**e)
更新返回的dict,使其包含e
中的所有键和值(如果当前值存在,则替换它们,这可能是错误或功能-示例中没有任何重叠,或者如果存在重叠,则说明应该发生什么)您当前如何操作,而该实现的具体问题是什么(如果问题是它不存在,那么首先修复它…)我没有看到多少证据表明您已经尝试自己解决这个问题。我已经尝试并获得了使用for循环的解决方案。但是我想知道是否有一种更直观的方法来做这件事我在我的答案中增加了另一种方法,那就是使用列表理解。我不确定这是否更直观。在我看来,对于复杂的嵌套循环,简单的“for循环”更直观,因为生成的代码更具可读性。然而,对于单循环,我发现列表的理解通常更清晰。
d={}
for e in listA:
t = e["time"]
d.setdefault(t, {}).update(**e)
for e in listB:
t = e["time"]
d.setdefault(t, {}).update(**e)
# get rid of "time" keys, if important to do so
for e in d.values():
del e["time"]