Reputation: 27
I have two list, one list containing dictionaries, the other list values.
l_dic = [
{
'a': 5,
'b': 7,
'c': [1,2,3,4,5]
},
{
'a': 12,
'b': 4,
'c': [1,2,3,4,5]
}
]
val = [458,646]
Now I'm trying to add the values to the dictionaries, so the result is looking like this:
res_dic = [
{
'a': 5,
'b': 7,
'c': [1,2,3,4,5],
'd': 458
},
{
'a': 12,
'b': 4,
'c': [1,2,3,4,5],
'd': 646
}
]
How can I achieve this?
Upvotes: 2
Views: 107
Reputation: 400
You can try the map
function which takes a function and an iterable as arguments and applies the function to each element in the iterable parallelly utilizing all the cores on your machine
l_dic = [
{
'a': 5,
'b': 7,
'c': [1,2,3,4,5]
},
{
'a': 12,
'b': 4,
'c': [1,2,3,4,5]
}
]
val = [458,646]
def assign(x):
l_dic[x]['d'] = val[x]
#runs paralelly utilizing all cores on your machine
ignore_this = [*map(lambda x: assign(x),range(len(l_dic)))]
Output
l_dic
{'a': 5, 'b': 7, 'c': [1, 2, 3, 4, 5], 'd': 458},
{'a': 12, 'b': 4, 'c': [1, 2, 3, 4, 5], 'd': 646}]
Upvotes: 0
Reputation: 17322
you can use python built-in function zip
with list comprehension
l_dic = [{**d, 'd': e} for d, e in zip(l_dic, val)]
output:
[
{
"a": 5,
"b": 7,
"c": [1, 2, 3, 4, 5],
"d": 458
},
{
"a": 12,
"b": 4,
"c": [1, 2, 3, 4, 5],
"d": 646
}
]
or you can use a for loop:
for d, v in zip(l_dic, val):
d['d'] = v
here is a benchmark of the proposed solutions:
from simple_benchmark import BenchmarkBuilder
b = BenchmarkBuilder()
@b.add_function()
def kederrac_for_loop(args):
l_dic, val = args
for d, v in zip(l_dic, val):
d['d'] = v
@b.add_function()
def kederrac_list_comprehension(args):
l_dic, val = args
l_dic = [{**d, 'd': e} for d, e in zip(l_dic, val)]
@b.add_function()
def GoodDeeds_for_loop(args):
l_dic, val = args
for i in range(len(val)):
l_dic[i]['d'] = val[i]
@b.add_function()
def Nizam_solution(args) :
l_dic, val = args
def assign(x):
l_dic[x]['d'] = val[x]
#runs paralelly utilizing all cores on your machine
ignore_this = [*map(lambda x: assign(x),range(len(l_dic)))]
@b.add_arguments('Number of elements')
def argument_provider():
for exp in range(2, 16):
size = 2**exp
l_dic = [{i : choice(range(100)) for i in range(choice(range(3, 100)))} for _ in range(size)]
val = list(range(size))
yield size, (l_dic, val)
r = b.run()
r.plot()
output:
as you can see the for loop solution is the fastest one
Upvotes: 2
Reputation: 2776
This problem is a little undefined, since the exact pattern of your keys isn't really defined beyond 26 items, but with some assumptions, you can work with it. What we'll do is zip()
your list of dictionaries and your list of items, and do the assignment on a line-by-line basis.
def dict_list_apply(dict_list:list, items_list:list):
def get_next_key(_dict):
ab = "abcdefghijklmnopqrstuvwxyz"
return ab[len(_dict)%len(ab)] * (len(_dict)//len(ab)+1)
for _dict, _item in zip(dict_list, items_list):
_dict[get_next_key(_dict)] = _item
The above code will insert items with keys in the following pattern:
a, b, ..., y, z, aa, bb, ..., yy, zz, aaa, bbb, ..., etc.
This means that we can indefinitely continue to add keys to each dictionary, regardless of the length of the other dictionaries.
Then, if we run something like this:
l_dic = [
{
'a': 5,
'b': 7,
'c': [1,2,3,4,5]
},
{
'a': 12,
'b': 4,
'c': [1,2,3,4,5]
}
]
val = [458,646]
for x in range(100):
dict_list_apply(l_dic, map(lambda v: v + x, val))
pprint.pprint(l_dic)
Then we get the following output:
[{'a': 5, 'aa': 481, 'aaa': 507, 'aaaa': 533, 'b': 7, 'bb': 482, 'bbb': 508, 'bbbb': 534, 'c': [1, 2, 3, 4, 5], 'cc': 483, 'ccc': 509, 'cccc': 535, 'd': 458, 'dd': 484, 'ddd': 510, 'dddd': 536, 'e': 459, 'ee': 485, 'eee': 511, 'eeee': 537, 'f': 460, 'ff': 486, 'fff': 512, 'ffff': 538, 'g': 461, 'gg': 487, 'ggg': 513, 'gggg': 539, 'h': 462, 'hh': 488, 'hhh': 514, 'hhhh': 540, 'i': 463, 'ii': 489, 'iii': 515, 'iiii': 541, 'j': 464, 'jj': 490, 'jjj': 516, 'jjjj': 542, 'k': 465, 'kk': 491, 'kkk': 517, 'kkkk': 543, 'l': 466, 'll': 492, 'lll': 518, 'llll': 544, 'm': 467, 'mm': 493, 'mmm': 519, 'mmmm': 545, 'n': 468, 'nn': 494, 'nnn': 520, 'nnnn': 546, 'o': 469, 'oo': 495, 'ooo': 521, 'oooo': 547, 'p': 470, 'pp': 496, 'ppp': 522, 'pppp': 548, 'q': 471, 'qq': 497, 'qqq': 523, 'qqqq': 549, 'r': 472, 'rr': 498, 'rrr': 524, 'rrrr': 550, 's': 473, 'ss': 499, 'sss': 525, 'ssss': 551, 't': 474, 'tt': 500, 'ttt': 526, 'tttt': 552, 'u': 475, 'uu': 501, 'uuu': 527, 'uuuu': 553, 'v': 476, 'vv': 502, 'vvv': 528, 'vvvv': 554, 'w': 477, 'ww': 503, 'www': 529, 'wwww': 555, 'x': 478, 'xx': 504, 'xxx': 530, 'xxxx': 556, 'y': 479, 'yy': 505, 'yyy': 531, 'yyyy': 557, 'z': 480, 'zz': 506, 'zzz': 532}, {'a': 12, 'aa': 669, 'aaa': 695, 'aaaa': 721, 'b': 4, 'bb': 670, 'bbb': 696, 'bbbb': 722, 'c': [1, 2, 3, 4, 5], 'cc': 671, 'ccc': 697, 'cccc': 723, 'd': 646, 'dd': 672, 'ddd': 698, 'dddd': 724, 'e': 647, 'ee': 673, 'eee': 699, 'eeee': 725, 'f': 648, 'ff': 674, 'fff': 700, 'ffff': 726, 'g': 649, 'gg': 675, 'ggg': 701, 'gggg': 727, 'h': 650, 'hh': 676, 'hhh': 702, 'hhhh': 728, 'i': 651, 'ii': 677, 'iii': 703, 'iiii': 729, 'j': 652, 'jj': 678, 'jjj': 704, 'jjjj': 730, 'k': 653, 'kk': 679, 'kkk': 705, 'kkkk': 731, 'l': 654, 'll': 680, 'lll': 706, 'llll': 732, 'm': 655, 'mm': 681, 'mmm': 707, 'mmmm': 733, 'n': 656, 'nn': 682, 'nnn': 708, 'nnnn': 734, 'o': 657, 'oo': 683, 'ooo': 709, 'oooo': 735, 'p': 658, 'pp': 684, 'ppp': 710, 'pppp': 736, 'q': 659, 'qq': 685, 'qqq': 711, 'qqqq': 737, 'r': 660, 'rr': 686, 'rrr': 712, 'rrrr': 738, 's': 661, 'ss': 687, 'sss': 713, 'ssss': 739, 't': 662, 'tt': 688, 'ttt': 714, 'tttt': 740, 'u': 663, 'uu': 689, 'uuu': 715, 'uuuu': 741, 'v': 664, 'vv': 690, 'vvv': 716, 'vvvv': 742, 'w': 665, 'ww': 691, 'www': 717, 'wwww': 743, 'x': 666, 'xx': 692, 'xxx': 718, 'xxxx': 744, 'y': 667, 'yy': 693, 'yyy': 719, 'yyyy': 745, 'z': 668, 'zz': 694, 'zzz': 720}]
Now, this isn't the only way to generate keys, so you can change that by modifying the get_next_key
function to provide the pattern that you want.
Upvotes: 0
Reputation: 8507
You can just use a loop:
for i in range(len(val)):
res_dic[i]['d'] = val[i]
assuming res_dic
and val
are lists of the same length.
Upvotes: 1