Python newbe在这里。我看过Stack Overflow但是找不到与此完全相似的问题。我试图合并一个具有相同键和值相同的dicts列表(所以在我的情况下合并名称是相同的)。
这是我目前的清单:
final = [
{
'name': 'food festival',
'category': ['Miscellaneous', 'Undefined'],
'shows': [
{
'start': '2017-10-04T14:30:00Z',
'venue': 'venue_1',
'prices': [
{ 'price_1' : 100 },
{ 'price_2' : 120}
]
},
{
'start': '2017-11-04T14:30:00Z',
'venue': 'venue_2',
'prices': [
{ 'price_1': 150 },
{ 'price_2' : 200 }
]
}
]
},
{
'name': 'music festival',
'category': ['music', 'pop'],
'shows': [
{
'start': '2017-12-04T14:30:00Z',
'venue': 'venue_3',
'prices': [
{ 'price_1' : 300 },
{ 'price_2' : 320}
]
}
]
}
]
这就是我想要实现的目标:
headers.append('Authorization', 'Bearer ${this.auth.token}');
答案 0 :(得分:1)
以下是一些代码:
from pprint import pprint as pp
current = [
{'name' : 'food festival', 'category' : ['Miscellaneous', 'Undefined'], 'venue' : 'venue_1', 'price_1' : 100, 'price_2' : 120, 'start' : '2017-10-04T14:30:00Z'},
{'name' : 'food festival', 'category' : ['Miscellaneous', 'Undefined'], 'venue' : 'venue_2', 'price_1' : 150, 'price_2' : 200, 'start' : '2017-11-04T14:30:00Z'},
{'name' : 'music festival', 'category': ['music', 'pop'], 'venue' : 'venue_3', 'price_1' : 300, 'price_2' : 320, 'start' : '2017-12-04T14:30:00Z'}
]
SPECIAL_EVENT_KEYS = ("name", "category")
INVALID_INDEX = -1
def convert_event(event, special_event_keys=SPECIAL_EVENT_KEYS):
ret = dict()
prices_list = list()
for key in event:
if key in special_event_keys:
continue
elif key.startswith("price_"):
prices_list.append({key: event[key]})
else:
ret[key] = event[key]
ret["prices"] = prices_list
return ret
def merge_events_data(events, special_event_keys=SPECIAL_EVENT_KEYS):
ret = list()
for event in events:
existing_index = INVALID_INDEX
for idx, obj in enumerate(ret):
for key in special_event_keys:
if obj[key] != event[key]:
break
else:
existing_index = idx
if existing_index == INVALID_INDEX:
new_object = dict()
for key in special_event_keys:
new_object[key] = event[key]
new_object["shows"] = [convert_event(event, special_event_keys=special_event_keys)]
ret.append(new_object)
else:
ret[existing_index]["shows"].append(convert_event(event, special_event_keys=special_event_keys))
return ret;
def main():
merged_events = merge_events_data(current)
print("\nResulting object:\n")
pp(merged_events)
#print("Equal:", merged_events == final) # Commented out to avoid including the contents of 'final' in the answer as it would get too large; add it and decomment for testing purpose
if __name__ == "__main__":
main()
备注强>:
name
和category
,它们将合并在一起(通过shows
列表),否则它们将是合并结果中的单独条目convert_event
:在初始列表中获取事件,并将其转换为输出列表的事件:
name
和category
键prices_*
条目聚合为与prices
键对应的列表merge_events_data
:迭代初始事件列表和
name
和category
值的条目),则会创建shows
)会使用当前事件数据进行扩充输出:
e:\Work\Dev\StackOverflow\q45794604>c:\Install\x64\Python\3.5.3\python.exe a.py Merged object: [{'category': ['Miscellaneous', 'Undefined'], 'name': 'food festival', 'shows': [{'prices': [{'price_2': 120}, {'price_1': 100}], 'start': '2017-10-04T14:30:00Z', 'venue': 'venue_1'}, {'prices': [{'price_2': 200}, {'price_1': 150}], 'start': '2017-11-04T14:30:00Z', 'venue': 'venue_2'}]}, {'category': ['music', 'pop'], 'name': 'music festival', 'shows': [{'prices': [{'price_2': 320}, {'price_1': 300}], 'start': '2017-12-04T14:30:00Z', 'venue': 'venue_3'}]}]
答案 1 :(得分:0)
您的数据结构有点令人困惑。我假设输入current
必须按原样修复,但我已将final
更改为更清晰。我认为这种格式的final
将更有用,更清晰,但如果你真的想要final
的其他版本,请告诉我。
import pprint
current = [
{'name' : 'food festival', 'category' : ['Miscellaneous', 'Undefined'], 'venue' : 'venue_1', 'price_1' : 100, 'price_2' : 120, 'start' : '2017-10-04T14:30:00Z'},
{'name' : 'food festival', 'category' : ['Miscellaneous', 'Undefined'], 'venue' : 'venue_2', 'price_1' : 150, 'price_2' : 200, 'start' : '2017-11-04T14:30:00Z'},
{'name' : 'music festival', 'category': ['music', 'pop'], 'venue' : 'venue_3', 'price_1' : 300, 'price_2' : 320, 'start' : '2017-12-04T14:30:00Z'}
]
final = {}
for fest in current:
name = fest["name"]
if name not in final:
final[name] = {"category": fest["category"],
"shows": []}
show = {attr: fest[attr] for attr in ["start", "venue", "price_1", "price_2"]}
final[name]["shows"].append(show)
pprint.pprint(final)
这有输出:
{'food festival': {'category': ['Miscellaneous', 'Undefined'],
'shows': [{'price_1': 100,
'price_2': 120,
'start': '2017-10-04T14:30:00Z',
'venue': 'venue_1'},
{'price_1': 150,
'price_2': 200,
'start': '2017-11-04T14:30:00Z',
'venue': 'venue_2'}]},
'music festival': {'category': ['music', 'pop'],
'shows': [{'price_1': 300,
'price_2': 320,
'start': '2017-12-04T14:30:00Z',
'venue': 'venue_3'}]}}
注意:我使用的字典理解可能特定于某些版本的Python3,我不确定。它可以很容易地替换为
show = dict((attr, fest[attr]) for attr in ["start", "venue", "price_1", "price_2"])
我没有太大改变 - 主要是最终版本是dict
,其中节日的名称是代表它的字典的关键,我只是保持{{1} }和price_1
作为键,因为它们只有两个,在我看来并不能证明词典列表是正确的。
另一个建议:您可以使用Python的price_2
对象而不是字符串"Undefined"
。