我找不到一个很好的方法来做到这一点。假设我有两个列表(列表中包含具有给定属性的对象)。我需要使用merged atttributes创建一个新的字典/列表。
listA = [
{
"alpha": "some value",
"time": "datetime",
},
...
]
listB = [
{
"beta": "some val",
"gamma": "some val",
"time": "datetime"
},
...
]
结果应如下(它应根据"时间"属性合并)
result = {
"datetime": {
"alpha": "some value",
"beta": "some val",
"gamma": "some val"
},
...
}
我如何以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"
}
}
答案 0 :(得分:2)
由于您正在搜索不使用for循环的替代方法,因此这是一个使用list comprehensions的实现,这会导致双线性。我不确定这是否比for循环更直观:
output = {}
[output.setdefault(item["time"],{}).update({key: value})
for key, value in item.items()
if key != "time"
for item in (listA + listB)]
对我而言,这只是一种更复杂的for循环方式...... setdefault的文档。
使用示例中提供的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'}}
答案 1 :(得分:1)
另一个答案,那可能更清晰,因为它避免了有利于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]
,则 t
会将d
创建为空字典,并返回d[t]
。然后.update(**e)
更新返回的dict以包含e
中的所有键和值(如果它们存在则替换当前值,这可能是错误或功能 - 示例没有任何重叠或说明应该是什么如果有重叠就会发生)
答案 2 :(得分:0)
这段代码可能是一个好的开始:
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)