how can I merge lists to create a python dictionary - python

So I have tried many methods to do this but could not find a working solution. In this problem, I have two python arrays and I would like to join them to create a big dictionary. It would go something like this:
`list1 = [
[2, "ford"],
[4,"Ferrari"],
[3, "Mercedes"],
[1, "BMW"]
]`
`list2 = [
[4, "mustang"],
[3,"LaFerrari"],
[2,"CLA"],
[1,"M5"],
[6,"opel"]
]`
The result that I would like to have is a dictionary that looks like this:
`result = {
1: ["BMW","M5"], 2: ["Ford","CLA"], 3: ["Mercedes","LaFerrari"], 4: ["Ferrari","Mustang"], 6:["Opel"]
}`
So it just basically needs to merge these two arrays based on the "key" (which is just the [0] place in the array)

It looks like task for collections.defaultdict I would do:
import collections
list1 = [
[1, "ford"],
[2,"Ferrari"],
[3, "Mercedes"],
[4, "BMW"]
]
list2 = [
[1, "mustang"],
[2,"LaFerrari"],
[3,"CLA"],
[4,"M5"]
]
result = collections.defaultdict(list)
for key, value in list1:
result[key].append(value)
for key, value in list2:
result[key].append(value)
result = dict(result)
print(result)
Output:
{1: ['ford', 'mustang'], 2: ['Ferrari', 'LaFerrari'], 3: ['Mercedes', 'CLA'], 4: ['BMW', 'M5']}
Here I used defaultdict with lists, unlike common dict if you try do something with value under key which do not exist yet, it did place list() i.e. empty list, then do requested action (appending in this case). At end I convert it into dict just to fullfill your requirement (create a python dictionary).

Use collections.defaultdict
from collections import defaultdict
result = defaultdict(list)
for k,v in list1 + list2:
result[k].append(v)
print (dict(result))
#{2: ['ford', 'CLA'], 4: ['Ferrari', 'mustang'], 3: ['Mercedes', 'LaFerrari'], 1: ['BMW', 'M5'], 6: ['opel']}

I am also pretty new to Python, but I think something like this should work if both lists have the same keys:
list1 = [
[1, "ford"],
[2, "Ferrari"],
[3, "Mercedes"],
[4, "BMW"]
]
list2 = [
[1, "mustang"],
[2, "LaFerrari"],
[3, "CLA"],
[4, "M5"]
]
dict1 = dict(list1)
dict2 = dict(list2)
result = {}
for key,val in dict1.items():
result[key] = [val]
for key, val in dict2.items():
result[key].append(val)
print(result)
output
{1: ['ford', 'mustang'], 2: ['Ferrari', 'LaFerrari'], 3: ['Mercedes', 'CLA'], 4: ['BMW', 'M5']}
As already mentioned, I am a newbie too, so there is probably a more "pythonic" way of doing this.

First, create a dict using the values in list1. Then update the lists in the dict with the values from list2, or create new lists for the keys in list2 which don't exist in list1:
result = {i: [j] for i, j in list1} # create initial dict from all values in list1
for i, j in list2:
if i in result:
result[i].append(j) # add to preexisting list corresponding to key
else:
result[i] = [j] # create new list corresponding to key
If your lists will have multiple values, you can use this where you handle the add logic in a separate function:
result = {}
def add_to_dict(d, key, val):
if key in d:
d[key].append(val)
else:
d[key] = [val]
for el in (list1 + list2):
key, *vals = el
for val in vals:
add_to_dict(result, key, val)
Here, rather than assuming each sublist has only 2 elements, we can unpack the key as the first element and the rest of the elements into a list called vals. Then, we can iterate over the list and perform the same adding logic

If you're sure that both lists contain the same number of items and both has a matching first element in each item (1, 2, 3, 4 in your example),
result = {k: [dict(list1)[k], dict(list2)[k]] for k in dict(list1)}

Related

How to extend a dictionnary in a such way?

I've got this project about stats and I just wondered how to create a list from a dictionnary like this:
{1:3, 2:4} => [1,1,1,2,2,2,2]
Thanks you !
This simple snippet should do it
l = []
for k, v in d.items():
l.extend([k] * v)
You can use list comprehension as:
x = {1:3, 2:4}
res = [k for k, v in x.items() for i in range(v)]
print(res)
Output:
[1, 1, 1, 2, 2, 2, 2]
we can easily do this by getting the keys of the dictionary. so basically 1 and 2 is our keys and its values are the times that it required to be added to list so we will use for loop to achieve the same.
myDict = { 1:3, 2:4 }
myList = list()
for key in myDict.keys():
for i in range(myDict[key]):
myList.append(key)
print(myList)
In above code the first loop will get the keys and the second will iterate to the limit and append the key into the list

Python: How to append list item to dictionary if item equals key?

I'm attempting to iterate through a list and if the list item equals a dictionary key, append the list item to the dictionary.
mylist = [1, 2, 3]
mydict = dict.fromkeys(mylist, [])
for item in mylist:
for key in mydict:
if key == item:
mydict[key].append(item)
print(mydict)
Output:
{1: [1, 2, 3], 2: [1, 2, 3], 3: [1, 2, 3]}
Required output:
{1: [1], 2: [2], 3: [3]}
Much thanks!
That's because here:
mydict = dict.fromkeys(mylist, [])
mydict's values will be the same object [], so when you append to mydict[something], you'll be appending to the same list, no matter what something is.
All values are the same object, you append three numbers to it => all values are shown as the same list.
To avoid this, assign new lists to each key:
mydict = {}
for item in mylist:
mydict.setdefault(item, []).append(item)
Or, you know:
mydict = {key: [key] for key in mylist}
by using:
mylist = [1, 2, 3]
mydict = dict.fromkeys(mylist, [])
you are creating a dict that has all the elements from mylist as keys and all the values from your dict are references to the same list, to fix you may use:
mydict = dict.fromkeys(mylist)
for item in mylist:
mydict[item] = [item]
print(mydict)
output:
{1: [1], 2: [2], 3: [3]}
same thing but in a more efficient and compact form by using a dictionary comprehension:
mydict = {item: [item] for item in mylist}
Is this what you wanted?
mylist = [1,2,3,3]
mydict = {}
for item in mylist:
if item not in mydict:
mydict[item] = [item]
else:
mydict[item].append(item)
print(mydict)
It will output: {1: [1], 2: [2], 3: [3, 3]}
mylist = [1, 2, 3]
mydict = dict.fromkeys(mylist, [])
for item in mylist:
for key in mydict:
if key == item:
mydict[key] = [item]
print(mydict)

Python: sort elements of first list by elements of second list

dict = {“Liz”: 4, “Garry”: 4, “Barry”:6}
list1 = []
for m in sorted(result_dict, key=result_dict.get, reverse=True):
list1.append(m)
After that we have two lists:
list1 = ["Barry","Liz", "Garry"]
list2 = [“Garry”, “Liz”, “Barry”]
I want that output be like - if elements had same value in dict, in list1 they should be in order of list2 -> for example, if Garry was first in list2, in list1 he too sould be first after "Barry":
list1 = ["Barry", "Garry", "Liz"]
The key function can return a tuple to break ties. So in your case
d = {"Liz": 4, "Garry": 4, "Barry": 6}
list2 = ["Garry", "Liz", "Barry"]
list1 = sorted(d, key=lambda x: (d.get(x), -list2.index(x)), reverse=True)
print(list1)
will print
['Barry', 'Garry', 'Liz']
You need to use as a key the combination of your current key with the positions on the second list, something like this:
dict = {'Liz': 4, 'Garry': 4, 'Barry': 6}
list2 = ['Garry', 'Liz', 'Barry']
dict2 = {key: i for i, key in enumerate(list2)}
list1 = sorted(dict, key=lambda x: (dict.get(x), -1*dict2.get(x)), reverse=True)
print(list1)
Output
['Barry', 'Garry', 'Liz']
This approach is faster for large list than using list.index. In fact calling index will make the complexity of the algorithm O(n*2) therefore hindering the expected complexity of the sorting algorithm which is O(n*logn) using a dictionary will keep it the same.

Remove duplicates and combine multiple lists into one?

How do I remove duplicates and combine multiple lists into one like so:
function([["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]) should return exactly:
[["good", ["me.txt", "money.txt"]], ["hello", ["me.txt"]], ["rep", ["money.txt"]]]
The easiest one would be using defaultdict .
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for i,j in l:
d[i].append(j) #append value to the key
>>> d
=> defaultdict(<class 'list'>, {'hello': ['me.txt'], 'good': ['me.txt', 'money.txt'],
'rep': ['money.txt']})
#to get it in a list
>>> out = [ [key,d[key]] for key in d]
>>> out
=> [['hello', ['me.txt']], ['good', ['me.txt', 'money.txt']], ['rep', ['money.txt']]]
#driver values :
IN : l = [["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]
Try This ( no library needed ):
your_input_data = [ ["hello","me.txt"], ["good","me.txt"], ["good","me.txt"], ["good","money.txt"], ["rep", "money.txt"] ]
my_dict = {}
for box in your_input_data:
if box[0] in my_dict:
buffer_items = []
for items in box[1:]:
if items not in my_dict[box[0]]:
buffer_items.append(items)
remove_dup = list(set(buffer_items + my_dict[box[0]]))
my_dict[box[0]] = remove_dup
else:
buffer_items = []
for items in box[1:]:
buffer_items.append(items)
remove_dup = list(set(buffer_items))
my_dict[box[0]] = remove_dup
last_point = [[keys, values] for keys, values in my_dict.items()]
print(last_point)
Good Luck ...
You can do it with traditional dictionaries too.
In [30]: l1 = [["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]
In [31]: for i, j in l1:
...: if i not in d2:
...: d2[i] = j
...: else:
...: val = d2[i]
...: d2[i] = [val, j]
...:
In [32]: d2
Out[32]: {'good': ['me.txt', 'money.txt'], 'hello': 'me.txt', 'rep': 'money.txt'}
In [33]: out = [ [key,d1[key]] for key in d1]
In [34]: out
Out[34]:
[['rep', ['money.txt']],
['hello', ['me.txt']],
['good', ['me.txt', 'money.txt']]]
Let's first understand the actual problem :
Example Hint :
For these types of list problems there is a pattern :
So suppose you have a list :
a=[(2006,1),(2007,4),(2008,9),(2006,5)]
And you want to convert this to a dict as the first element of the tuple as key and second element of the tuple. something like :
{2008: [9], 2006: [5], 2007: [4]}
But there is a catch you also want that those keys which have different values but keys are same like (2006,1) and (2006,5) keys are same but values are different. you want that those values append with only one key so expected output :
{2008: [9], 2006: [1, 5], 2007: [4]}
for this type of problem we do something like this:
first create a new dict then we follow this pattern:
if item[0] not in new_dict:
new_dict[item[0]]=[item[1]]
else:
new_dict[item[0]].append(item[1])
So we first check if key is in new dict and if it already then add the value of duplicate key to its value:
full code:
a=[(2006,1),(2007,4),(2008,9),(2006,5)]
new_dict={}
for item in a:
if item[0] not in new_dict:
new_dict[item[0]]=[item[1]]
else:
new_dict[item[0]].append(item[1])
print(new_dict)
Your actual problem solution :
list_1=[["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]
no_dublicates={}
for item in list_1:
if item[0] not in no_dublicates:
no_dublicates[item[0]]=["".join(item[1:])]
else:
no_dublicates[item[0]].extend(item[1:])
list_result=[]
for key,value in no_dublicates.items():
list_result.append([key,value])
print(list_result)
output:
[['hello', ['me.txt']], ['rep', ['money.txt']], ['good', ['me.txt', 'money.txt']]]
yourList=[["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]
expectedList=[["good", ["me.txt", "money.txt"]], ["hello", ["me.txt"]], ["rep", ["money.txt"]]]
def getall(allsec, listKey, uniqlist):
if listKey not in uniqlist:
uniqlist.append(listKey)
return [listKey, [x[1] for x in allsec if x[0] == listKey]]
uniqlist=[]
result=sorted(list(filter(lambda x:x!=None, [getall(yourList,elem[0],uniqlist) for elem in yourList])))
print(result)
hope this helps
This can easily be solved using dict and sets.
def combine_duplicates(given_list):
data = {}
for element_1, element_2 in given_list:
data[element_1] = data.get(element_1, set()).add(element_2)
return [[k, list(v)] for k, v in data.items()]
Using Python to create a function that gives you the exact required output can be done as follows:
from collections import defaultdict
def function(data):
entries = defaultdict(list)
for k, v in data:
entries[k].append(v)
return sorted([k, v] for k, v in entries.items())
print(function([["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]))
The output is sorted before being returned as per your requirement. This would display the return from the function as:
[['good', ['me.txt', 'money.txt']], ['hello', ['me.txt']], ['rep', ['money.txt']]]
It also ensures that the keys are sorted. A dictionary is used to deal with the removal of duplicates (as keys need to be unique).
A defaultdict() is used to simplify the building of lists within the dictionary. The alternative would be to try and append a new value to an existing key, and if there is a KeyError exception, then add the new key instead as follows:
def function(data):
entries = {}
for k, v in data:
try:
entries[k].append(v)
except KeyError as e:
entries[k] = [v]
return sorted([k, v] for k, v in entries.items())
Create a empty array push the index 0 from childs arrays and join to convert all values to a string separate by space .
var your_input_data = [ ["hello","hi", "jel"], ["good"], ["good2","lo"], ["good3","lt","ahhahah"], ["rep", "nice","gr8", "job"] ];
var myprint = []
for(var i in your_input_data){
myprint.push(your_input_data[i][0]);
}
console.log(myprint.join(' '))

I need to iterate through a dictionary and see if keys are in a given list

Given a dictionary d and a list lst, remove all elements from the dictionary whose key is an element of lst. Any elements from the list that are NOT keys of the dictionary should be added to a new set associated with the variable  not_found. For example, given the dictionary {1:2, 3:4, 5:6, 7:8} and the list [1, 6, 7], the resulting dictionary would be {3:4, 5:6} and the set not_found would contain 6.
this is what my code looks like:
not_found = ()
for i in d:
if d[i] in lst:
not_found.append(d[i])
del d[i]
You don't want to delete elements of any dict while you are iterating over it. Also, you would be better off iterating over lst rather than the dictionary d to take advantage of its constant time lookup. The way you are doing it now is to iterate over the dict then iterate over the list, each time. This isn't ideal. Try something like,
not_found = set()
for e in lst:
if e in d:
del d[e]
else:
not_found.add(e)
print d # {3: 4, 5: 6}
print not_found # set([6])
Deleting from a list/dict while iterating over it will cause you to skip over items. dict should complain if the size changes while you are iterating over it.
Usually it's best to create a new dict with the items you need to keep
In your case it's netter to iterate over lst instead
>>> d = {1:2, 3:4, 5:6, 7:8}
>>> lst = [1, 6, 7]
>>> not_found = {k for k in lst if k not in d}
>>> for k in lst:
... if k in d:
... del d[k]
>>> d
{3: 4, 5: 6, 7: 8}
for i in lst:
if i in d:
del d[i]

Categories