2017-08-21 102 views
-1

python newbe here。我看过堆栈溢出,但无法找到与此类似的问题。我想合并具有相同键和值的字典列表是相同的(所以在我的情况下合并的名称是相同的)。如何合并具有相同键的字典列表,其值相同?

这是我当前列表:

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 = [ 
    { 
    '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} 
     ] 
     } 
    ] 
    } 
] 
+0

您对“价格”键改变看起来比刚才键合并更复杂..你确定你想要“价格”是一个长度单一的列表? –

+0

是的,这将是最想要的结果 - 也许我应该在标题和解释中更清楚一点。 –

+0

我想@IzaakvanDongen,为什么不使用一个列表和索引是价格? 'prices':[300,320'] – SD3L

回答

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() 

注意

  • 的算法依赖于一个事实,即如果2(输入)事件对键的值相同:namecategory,他们将合并在一起(通过shows名单),否则他们将在合并结果中单独进入
  • convert_event:需要一个事件喜欢它的初始列表,并将其转换为事件的输出列表:
    • 条出namecategory
    • 聚集prices_*条目在字典中的列表对应prices关键
  • merge_events_data:初始事件列表上进行迭代,并且
    • 如果事件不存在在输出列表(具有匹配namecategory值没有条目)时,它创建它
    • 如果找到这样一个事件,其含量(shows)被增大与当前事件数据
  • 代码为Python3Python2兼容
  • 绝对可以从风格和性能POV

输出提高:

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'}]}] 
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,在节日的名字是代表它的钥匙字典,而我只是不停price_1price_2作为键,因为它们只有两个,它们在我脑海中并没有真正证明字典列表的正确性。

另一个建议:而不是字符串"Undefined",你可以使用Python的None对象。

相关问题