Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specific list format Python

Tags:

python

I have researched a lot of similar questions but I can't seem to find a solution on them or on my own. What I want to achieve is to get two dictionaries of this form each:

{'apple': ['5', '65'], 'blue': ['9', '10', '15', '43'],
'is': ['5', '6', '13', '45', '96'], 'yes': ['1', '2', '3', '11'], 
'zone': ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']}

{'apple': ['43'], 'appricote': ['1', '2', '3', '4', '5', '6'],
'candle': ['1', '2', '4', '5', '6', '9'], 'delta': ['14', '43', '47'], 
'dragon': ['23', '24', '25', '26'], 'eclipse': ['11', '13', '15', '19'], 
'island': ['1', '34', '35']}

And I want to have to following format:

apple ['5', '43', '65']
apricot ['1', '2', '3', '4', '5', '6']
blue ['9', '10', '15', '43']
candle ['1', '2', '4', '5', '6', '9']
delta ['14', '43', '47']
dragon ['23', '24', '25', '26']
eclipse ['11', '13', '15', '19']
is ['5', '6', '13', '45', '96']
island ['1', '34', '35']
yes ['1', '2', '3', '11']
zone ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']

But this is the format I get:

apple [['5', '65'], ['43']]
blue [['9', '10', '15', '43']]
is [['5', '6', '13', '45', '96']]
yes [['1', '2', '3', '11']]
zone [['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']]
appricote [['1', '2', '3', '4', '5', '6']]
candle [['1', '2', '4', '5', '6', '9']]
delta [['14', '43', '47']]
dragon [['23', '24', '25', '26']]
eclipse [['11', '13', '15', '19']]
island [['1', '34', '35']]

This is my code so far

def merge_dictionaries(dict1, dict2): 
    from itertools import chain
    from collections import defaultdict

    dict3 = defaultdict(list)
    for k, v in chain(dict1.items(), dict2.items()):
        dict3[k].append(v)

    for k, v in dict3.items():
        print(k, v)

So my question is should I further process the format I have now or is it possible to achieve the format I want straight away. For example if you tell me to process the format I already have achieved I can merge the sub-lists into one list for each key and then sort, and the sort the keys also. But I want to know if there is a more direct way.

like image 487
V g Avatar asked Jan 28 '23 05:01

V g


2 Answers

You need to use list.extend and not list.append:

>>> d = defaultdict(list)
>>> for k,v in chain(dict1.items(), dict2.items()):
...     d[k].extend(v)
... 
>>> d
defaultdict(<class 'list'>, {'apple': ['5', '65', '43'], 'blue': ['9', '10', '15', '43'], 'is': ['5', '6', '13', '45', '96'], 'yes': ['1', '2', '3', '11'], 'zone': ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45'], 'appricote': ['1', '2', '3', '4', '5', '6'], 'candle': ['1', '2', '4', '5', '6', '9'], 'delta': ['14', '43', '47'], 'dragon': ['23', '24', '25', '26'], 'eclipse': ['11', '13', '15', '19'], 'island': ['1', '34', '35']})

You could sort the resulting lists if their order is important.

like image 188
Chris_Rands Avatar answered Jan 31 '23 08:01

Chris_Rands


Your code is too complex.

a = {'apple': ['5', '65'], 'blue': ['9', '10', '15', '43'],
     'is': ['5', '6', '13', '45', '96'], 'yes': ['1', '2', '3', '11'],
     'zone': ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']}

b = {'apple': ['43'], 'appricote': ['1', '2', '3', '4', '5', '6'],
     'candle': ['1', '2', '4', '5', '6', '9'], 'delta': ['14', '43', '47'],
     'dragon': ['23', '24', '25', '26'], 'eclipse': ['11', '13', '15', '19'],
     'island': ['1', '34', '35']}

output = []
for key in a:
    temp = a[key]
    if key in b:
        temp.extend(b[key])
    output.append('{} {}'.format(key, sorted(temp)))

print('\n'.join(output))

# is ['13', '45', '5', '6', '96']
# blue ['10', '15', '43', '9']
# zone ['10', '12', '14', '18', '19', '29', '45', '5', '6', '9']
# apple ['43', '5', '65']
# yes ['1', '11', '2', '3']

Caveats:

  • Since a is a dictionary the order of the elements in the outputted string is not persistent (in Python <= 3.6)

  • Since your values are strings they are sorted lexicographically.

Both of these points can easily be fixed if they are relevant.

like image 35
DeepSpace Avatar answered Jan 31 '23 08:01

DeepSpace