2
u= [['1', '2'], ['3'], ['4', '5', '6'], ['7', '8', '9', '10']]
v=[{'id': 'a', 'adj': ['blue', 'yellow']}, {'id': 'b', 'adj': ['purple', 'red']}, {'id': 'c', 'adj': ['green', 'orange']}, {'id': 'd', 'adj': ['black', 'purple']}]

I want:

 result=[ {'id': 'a', 'adj': ['blue', 'yellow'], 'value': '1' },
        {'id': 'a', 'adj': ['blue', 'yellow'], 'value': '2' },
        {'id': 'a', 'adj': ['purple', 'red'], 'value': '3' },
        ...]

I've converted u to a dictionary:

m=[]
for i in u:
    s={}
    s['value']=i
    m.append(s)

#>>m= [{'value': ['1', '2']}, {'value': ['3']}, {'value': ['4', '5', '6']}, {'value': ['7', '8', '9', '10']}]

Then tried to applied zip function...

for i,j in enumerate(v):
    for s,t in enumerate(l):
        if i= =s:
            #zip 2 dictionary together. Stuck here

Thanks a lot in advance! This is my 2nd week of learning programming.

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
el347
  • 87
  • 8

3 Answers3

0

You need to zip, iterate over each sublist from u,deepcopy each dict from v and add the new key/value pairing, finally append the new dict to a list:

from copy import deepcopy

u= [['1', '2'], ['3'], ['4', '5', '6'], ['7', '8', '9', '10']]
v=[{'id': 'a', 'adj': ['blue', 'yellow']}, {'id': 'b', 'adj': ['purple', 'red']}, {'id': 'c', 'adj': ['green', 'orange']}, {'id': 'd', 'adj': ['black', 'purple']}]

out = []
# match up corresponding elements fromm both lists
for dct, sub in zip(v, u):
    # iterate over each sublist
    for val in sub:
        # deepcopy the dict as it contains mutable elements (lists)
        dct_copy = deepcopy(dct)
        # set the new key/value pairing
        dct_copy["value"] = val
        # append the dict to our out list
        out.append(dct_copy)
from pprint import pprint as pp
pp(out)

Which will give you:

[{'adj': ['blue', 'yellow'], 'id': 'a', 'value': '1'},
 {'adj': ['blue', 'yellow'], 'id': 'a', 'value': '2'},
 {'adj': ['purple', 'red'], 'id': 'b', 'value': '3'},
 {'adj': ['green', 'orange'], 'id': 'c', 'value': '4'},
 {'adj': ['green', 'orange'], 'id': 'c', 'value': '5'},
 {'adj': ['green', 'orange'], 'id': 'c', 'value': '6'},
 {'adj': ['black', 'purple'], 'id': 'd', 'value': '7'},
 {'adj': ['black', 'purple'], 'id': 'd', 'value': '8'},
 {'adj': ['black', 'purple'], 'id': 'd', 'value': '9'},
 {'adj': ['black', 'purple'], 'id': 'd', 'value': '10'}]

dicts have a .copy attribute or you could call dict(dct) but because you have mutable object as values, just doing a shallow copy will not work. The example below shows you the actual difference:

In [19]: d = {"foo":[1, 2, 4]}

In [20]: d1_copy = d.copy() # shallow copy, same as dict(d)

In [21]: from copy import  deepcopy

In [22]: d2_copy = deepcopy(d) # deep copy

In [23]: d["foo"].append("bar")

In [24]: d
Out[24]: {'foo': [1, 2, 4, 'bar']}

In [25]: d1_copy
Out[25]: {'foo': [1, 2, 4, 'bar']} # copy also changed

In [26]: d2_copy
Out[26]: {'foo': [1, 2, 4]} # deepcopy is still the same

what-exactly-is-the-difference-between-shallow-copy-deepcopy-and-normal-assignment

Community
  • 1
  • 1
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • wow!!! thank so much!!! how did u do it so fast?! I gonna take a good half an hour to study this. I spent about 2 hours trying to figure this out. Thank you <333 ^.^ – el347 Aug 15 '16 at 22:48
  • @el347, no worries, take note of the difference between a shallow and deepcopy when you have mutable objects inside the dict, the same logic applies to lists etc.. and often catches people out – Padraic Cunningham Aug 15 '16 at 22:55
0

Apply zip on both lists, and create a new dictionary where the old ones have the values from the corresponding list added as the key-value entry value: number from list:

>>> import pprint, copy
>>> result = [dict(copy.deepcopy(j), value = ind) for i, j in zip(u, v) for ind in i]
>>> pprint.pprint(result)
[{'adj': ['blue', 'yellow'], 'id': 'a', 'value': '1'},
 {'adj': ['blue', 'yellow'], 'id': 'a', 'value': '2'},
 {'adj': ['purple', 'red'], 'id': 'b', 'value': '3'},
 {'adj': ['green', 'orange'], 'id': 'c', 'value': '4'},
 {'adj': ['green', 'orange'], 'id': 'c', 'value': '5'},
 {'adj': ['green', 'orange'], 'id': 'c', 'value': '6'},
 {'adj': ['black', 'purple'], 'id': 'd', 'value': '7'},
 {'adj': ['black', 'purple'], 'id': 'd', 'value': '8'},
 {'adj': ['black', 'purple'], 'id': 'd', 'value': '9'},
 {'adj': ['black', 'purple'], 'id': 'd', 'value': '10'}]
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
0

You can use the following code to acquire the desired result.

result = []
for index, d in enumerate(u):
    for value in d:
        result.append(dict(v[index], value=value))

It iterates over an enumerate-ion of u, and then appends a combination of the correct v dict and the value to the result list.

You can compress this into a relatively clean one-liner using a list comprehension.

result = [dict(v[index], value=value) for index, d in enumerate(u) for value in d]
2Cubed
  • 3,401
  • 7
  • 23
  • 40