I have 2 lists which i have created and added an incrementing value to each item. The reason being that the values in each list are to be joined together in a dictionary. However the values in each list are not a 1 to 1 pair..this is why i added the incrementing values to assist with associating each key with it's corresponding value(s).
Here is some example data from my lists:
list_a = ['abc|1','bcd|2','cde|3']
list_b = ['1234|1','2345|2','3456|2','4567|2','5678|3']
So ideally what i am looking to do is run through both lists and then produce a dictionary based on pairing by the incrementing values. I am guessing the values where applicable would have to be a list?
Below is the ideal output:
my_dict = {'abc|1':'1234|1','bcd|2':['2345|2','3456|2','4567|2'],'cde|3':'5678|3'}
Any help would be greatly appreciated, Thanks in advance :)
list_a = ['abc|1','bcd|2','cde|3']
list_b = ['1234|1','2345|2','3456|2','4567|2','5678|3']
tmp = {k.split('|')[1]: (k, []) for k in list_a}
for v in list_b:
tmp[v.split('|')[1]][1].append(v)
my_dict = dict(tmp.values())
This gets close to what you posted as goal, but I think it's actually better.
goal: {'abc|1': '1234|1', 'bcd|2': ['2345|2', '3456|2', '4567|2'], 'cde|3': '5678|3' }
mine: {'abc|1': ['1234|1'], 'bcd|2': ['2345|2', '3456|2', '4567|2'], 'cde|3': ['5678|3']}
You can see we only differ by putting singles into a list (me) or not (you). The reason I think my way is better is because any code using this result will likely be easier if all values are lists, so it doesn't need to handle both single strings and lists of strings. Just like it was easier for me to produce only lists.
But if you still prefer your way, change my above last line to:
my_dict = {k: v if len(v) > 1 else v[0] for k, v in tmp.values()}
You could make two dicts grouping with the first:
list_a = ['abc|1','bcd|2','cde|3']
list_b = ['1234|1','2345|2','3456|2','4567|2','5678|3']
d = defaultdict(list)
from itertools import chain
for k in chain(list_a,list_b):
d[k.rsplit("|",1)[1]].append(k)
print(d)
print({v[0]:v[1:] for v in d.values()})
defaultdict(<type 'list'>, {'1': ['abc|1', '1234|1'], '3': ['cde|3', '5678|3'], '2': ['bcd|2', '2345|2', '3456|2', '4567|2']})
{'abc|1': ['1234|1'], 'cde|3': ['5678|3'], 'bcd|2': ['2345|2', '3456|2', '4567|2']}
You can avoid the list for single values by checking the length first if required.
d = {v[0]: (v[1:] if len(v)> 2 else v[-1]) for v in d.values()}
print(d)
{'abc|1': '1234|1', 'cde|3': '5678|3', 'bcd|2': ['2345|2', '3456|2', '4567|2']}
Using python3 the syntax is a bit nicer using extended iterable unpacking:
d = {k: (val if len(val) > 1 else val[0]) for k,*val in d.values()}
print(d)
If you want order based on the keys in the lista you will need an OrderedDict:
list_a = ['abc|1', 'bcd|2', 'cde|3']
list_b = ['1234|1', '2345|2', '3456|2', '4567|2', '5678|3']
from collections import OrderedDict
from itertools import chain
od = OrderedDict()
for k in chain(list_a, list_b):
od.setdefault(k.rsplit("|",1)[1], []).append(k)
d = OrderedDict((k, (val)) for k, *val in od.values())
It can be achieved from something like this
temp_dict = {}
for x in list_a:
val = x.split('|')[1]
temp_dict[x] = [y for y in list_b if y.endswith("|" + val)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With