简体   繁体   中英

Creating a list of dictionaries with numerous key value pairs

I have multiple lists that I need to combine into a list of dictionaries with multiple key value pairs wherein the value could in itself contain a list - so for example:

namesIDs = [1, 2, 3, 4, 5]
namesList = ['jacksparrow', 'aragron', 'harrypotter', 'bilbo', 'einstein']
address = ['addr1', 'addr2', 'addr3', 'addr4', 'addr5']
parentsIDs = [11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44, 51, 52, 53, 54, 55, 56] 
parentsNames = ['Teague', 'MrsT', 'gPaT', 'gMaT', 'Arathorn', 'Gilraen', 'gPaAg', 'gMaAg', 'James', 'Lily', 'gPaHp', 'gMaHp', 'Bungo', 'Belladona', 'gPaB', 'gMaB', 'Herman', 'Pauline', 'Abraham', 'Helene', 'babyA', 'babyB']

The output I'm expecting is:

[{'nameIDs': 1, 'namesList': 'jacksparrow', 'address': 'addr1', 'parentsIDs': [11,12,13,14], 'parentsNames': ['Teague', 'MrsT', 'gPaT', 'gMaT']},
 {'nameIDs': 2, 'namesList': 'aragorn', 'address': 'addr2', 'parentsIDs': [21,22,23,24], 'parentsNames': ['Arathorn', 'Gilraen', 'gPaAg', 'gMaAg']},
 {'nameIDs': 3, 'namesList': 'harrypotter', 'address': 'addr3', 'parentsIDs': [31,32,33,34], 'parentsNames': ['James', 'Lily', 'gPaHp', 'gMaHp']},
 {'nameIDs': 4, 'namesList': 'bilbo', 'address': 'addr4', 'parentsIDs': [41,42,43,44], 'parentsNames': ['Bungo', 'Belladona', 'gPaB', 'gMaB']},
 {'nameIDs': 5, 'namesList': 'einstein', 'address': 'addr5', 'parentsIDs': [51,52,53,54,55,56], 'parentsNames': ['Bungo', 'Belladona', 'gPaB', 'gMaB', 'babyA', 'babyB']}
]

NOTICE the last item parentsIDs/parentsNames are LONGER than the rest. I've tried using zip and dict comprehension but it doens't work/make sense to me. Any help is greatly appreciated!

>>> namesIDs = [1, 2, 3, 4, 5]
>>> namesList = ['jacksparrow', 'aragron', 'harrypotter', 'bilbo', 'einstein']
>>> [dict(zip(('NameID', 'Name'), item )) for item in namesList]
[{'NameID': 'j', 'Name': 'a'}, {'NameID': 'a', 'Name': 'r'}, {'NameID': 'h', 'Name': 'a'}, {'NameID': 'b', 'Name': 'i'}, {'NameID': 'e', 'Name': 'i'}]

EDIT: PLEASE note that parentsIDs and parentsNames might be arbitrarily long and not necessarily be equal to each other in length. Both solutions below yield incorrect answers. I've updated the full expected output to prevent ambiguity.

You can create list of lists for last 2 lists and then use zip and list_comprehension .

namesIDs = [1, 2, 3, 4, 5]
namesList = ['jacksparrow', 'aragron', 'harrypotter', 'bilbo', 'einstein']
address = ['addr1', 'addr2', 'addr3', 'addr4', 'addr5']
parentsNames = ['Teague', 'MrsT', 'gPaT', 'gMaT', 'Arathorn', 'Gilraen', 'gPaAg', 'gMaAg', 'James', 'Lily', 'gPaHp', 'gMaHp', 'Bungo', 'Belladona', 'gPaB', 'gMaB', 'Herman', 'Pauline', 'Abraham', 'Helene']
parentsIDs = [11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44, 51, 52, 53, 54] 

parentsIDs = [parentsIDs[i:i+ int(len(parentsIDs)/len(namesIDs))] for i in range(0,len(parentsIDs),len(namesIDs))]
parentsNames = [parentsNames[i:i+ int(len(parentsNames)/len(namesIDs))] for i in range(0,len(parentsNames),len(namesIDs))]

final_dict = [{"nameIDs":n,"namesList":nl, "address":ad, 'parentsIDs':pid, 'parentsNames':pn} for n,nl,ad,pid,pn in zip(namesIDs,namesList,address,parentsIDs,parentsNames)]

print(final_dict)

You can use list slicing inside the following list comprehension.

out = [{'nameIDs': a, 'namesList': b, 'address': c, 
        'parentsIDs': parentsIDs[d:d+len(namesIDs)], 
        'parentsNames': parentsNames[e:e+len(namesIDs)]} 
       for a,b,c,d,e in zip(namesIDs, namesList, address, 
                            range(0, len(parentsIDs), len(namesIDs)), 
                            range(0, len(parentsNames), len(namesIDs)))]

Output:

[{'nameIDs': 1,
  'namesList': 'jacksparrow',
  'address': 'addr1',
  'parentsIDs': [11, 12, 13, 14, 21],
  'parentsNames': ['Teague', 'MrsT', 'gPaT', 'gMaT', 'Arathorn']},
 {'nameIDs': 2,
  'namesList': 'aragron',
  'address': 'addr2',
  'parentsIDs': [21, 22, 23, 24, 31],
  'parentsNames': ['Arathorn', 'Gilraen', 'gPaAg', 'gMaAg', 'James']},
 {'nameIDs': 3,
  'namesList': 'harrypotter',
  'address': 'addr3',
  'parentsIDs': [31, 32, 33, 34, 41],
  'parentsNames': ['James', 'Lily', 'gPaHp', 'gMaHp', 'Bungo']},
 {'nameIDs': 4,
  'namesList': 'bilbo',
  'address': 'addr4',
  'parentsIDs': [41, 42, 43, 44, 51],
  'parentsNames': ['Bungo', 'Belladona', 'gPaB', 'gMaB', 'Herman']},
 {'nameIDs': 5,
  'namesList': 'einstein',
  'address': 'addr5',
  'parentsIDs': [51, 52, 53, 54],
  'parentsNames': ['Herman', 'Pauline', 'Abraham', 'Helene']}]

Your specific example presents a pattern of parentsIDs that could possibly be leveraged. Each group is in a tens range (11..14, 21..24, ...) so we could use groupy to partition the parentsIDs list and islice over an iterator to group parentsNames with the same distribution:

from itertools import groupby,islice
d = [ {'nameIDs':ni, 'namesList':nl, 'address':ad,
       'parentIDs':pi, 'parentsNames':[*islice(pn,len(pi))] }
      for pn in [iter(parentsNames)]
      for ni,nl,ad,(pi,pi[:])
      in zip(namesIDs, namesList, address,
             groupby(parentsIDs,lambda i:[i//10]))]

Output:

[{'nameIDs': 1, 'namesList': 'jacksparrow', 'address': 'addr1', 'parentIDs': [11, 12, 13, 14], 'parentsNames': ['Teague', 'MrsT', 'gPaT', 'gMaT']},    
 {'nameIDs': 2, 'namesList': 'aragron', 'address': 'addr2', 'parentIDs': [21, 22, 23, 24], 'parentsNames': ['Arathorn', 'Gilraen', 'gPaAg', 'gMaAg']},    
 {'nameIDs': 3, 'namesList': 'harrypotter', 'address': 'addr3', 'parentIDs': [31, 32, 33, 34], 'parentsNames': ['James', 'Lily', 'gPaHp', 'gMaHp']},    
 {'nameIDs': 4, 'namesList': 'bilbo', 'address': 'addr4', 'parentIDs': [41, 42, 43, 44], 'parentsNames': ['Bungo', 'Belladona', 'gPaB', 'gMaB']},    
 {'nameIDs': 5, 'namesList': 'einstein', 'address': 'addr5', 'parentIDs': [51, 52, 53, 54, 55, 56], 'parentsNames': ['Herman', 'Pauline', 'Abraham', 'Helene', 'babyA', 'babyB']}]

Obviously this is just simulated data and the actual parentsIDs may not be groupable based on i//10 but, if you have any way to obtain a distinct grouping key from the parentsIDs values, this would allow you to form groupings of arbitrary sizes that correspond to the desired partitioning of these lists

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM