compare values from a list with values from a dictionary - python

I have a dictionary contains lists of values and a list:
dict={'first':45, 'second':30, 'third':56}
list= [30,45]
I want to compare the value in the dictionary with the list and a match to add to a new dictionary after that, remove from the old dict all the values that are in the new dict: I'm doing something like this:
def get_sessions(self, talks):
result_sessions = {}
for k, v in self.sessions.items():
for i in talks:
if v == i:
result_sessions[k] = v
for k, v in result_sessions.items():
del self.sessions[k]
return result_sessions
Maybe you know a more elegant solution? any help?

This is one approach.
Ex:
d ={'first':45, 'second':30, 'third':56}
lst = [30,45]
result_sessions = {k: v for k, v in d.items() if v in lst}
d = { k : d[k] for k in set(d) - set(result_sessions) }
print(result_sessions)
print(d)
Output:
{'second': 30, 'first': 45}
{'third': 56}

Related

Create a new dictionary from 2 existing dictionory (1 nested dictionory , 1 dictionory of lists) python

I have two dictionaries K and L. K is a Dictionary of lists and L is a nested dictionary
K={
'k1':[1,3,2],
'k2':[3,4,5],
'k3':[9,10,11]
}
L = {
'l1':{'a':'1','b':'1','c':'2'},
'l2':{'a':'1','b':'3','c':'2'},
'l3':{'a':'1','b':'2','c':'2'},
'l4':{'a':'1','b':'4','c':'2'}
}
What I need:
I want to create a new dictionary of lists based on the below condition.
I need to check if b values of L are present in the K dictionary of the list or not.
If present I need to return a new dictionary with Key of K
dictionary and Key of L dictionary.
For the above example, I need to return something like this
M = {'k1':[l1,l3,l2]
'k2':[l2,l4]
}
Here is the code that I have tried:
M= {}
for k, v in K.items():
temp = []
for i in v:
if L[i]['b'] in K[k]:
temp.append(i)
M[k] = temp
print(M)
Here is your solution:
new_dict, M = dict(), dict()
for key, val in L.items():
new_dict[val['b']] = key
for key, val in K.items():
for x in val:
if str(x) in new_dict:
tmp = new_dict[str(x)]
lst = M[key] if key in M else list()
lst.append(tmp)
M[key] = lst
print(M)
For the following K, L:
K = {
'k1':[1,3,2],
'k2':[3,4,5],
'k3':[9,10,11]
}
L = {
'l1':{'a':'1','b':'1','c':'2'},
'l2':{'a':'1','b':'3','c':'2'},
'l3':{'a':'1','b':'2','c':'2'},
'l4':{'a':'1','b':'4','c':'2'}
}
Output M:
M = {
'k2': ['l2', 'l4'],
'k1': ['l1', 'l2', 'l3']
}
[ Considered b values of L has a unique value, if not then you have to store it as a list in the new_dict dictionary.]
You were looking up the wrong thing in L here L[I]. I would do this by creating a lookup intially from L, that way you don't have to loop through L for every key in K. From there you can go through K once, looking up the items from the lookup.
Using defaultdict also allows you to handle the case where L has b values that are the same
from collections import defaultdict
b_val_to_l = defaultdict(set)
for lkey, ldict in L.items():
# For each ldict, extract the 'b' value, convert to an int and add the
# l key to the set of l values for the corresponding b value
b_val_to_l[int(ldict['b'])].add(lkey)
print(b_val_to_l)
M = defaultdict(list)
for k, v in K.items():
for i in v:
# For each value in the k, get the set of corresponding l values
b_set = b_val_to_l.get(i, set())
# Add to the output dict
M[k].extend(list(b_set))
print(M)
Just do this:
Mtemp = { k: [l for l in L
if int(L[l]['b']) in K[k]
] for k in K }
# Mtemp can have None values, so let's remove them...
M = { k: l for k, l in Mtemp.items() if len(l) > 0 }
Output:
{'k1': ['l1', 'l2', 'l3'], 'k2': ['l2', 'l4']}

Update dictionary and append if key exists

I've got a list of dictionarys.
list_of_dicts = [{ a: 1, b:f, c:3}, {a: y, b:q, c:z, d: 1}, ... ]
Now i want to create a new dictionary which looks like:
newDict = { a: [1,y], b: [f,q], c: [3,z], d:[1]}
I know i could could make a double for loop, but that is rather slow since I'm dealing with large objects (mostly NumPy arrays) in the dictionaries.
newDict = {}
for l in list_of_dicts:
for k, v in l.items():
if k in newDict:
newDict.append(v)
else:
newDict[k] = [v]
How to do this faster?
Using a collections.defaultdict() will improve the performance:
result = defaultdict(list)
for d in list_of_dicts:
for k, v in d.items():
result[k].append(v)
This is the fastest you can do this. You can replace the if with newdict.setdefault(k, []).append(v) to simplify it, but there is nothing you can do that will be faster than two loops.

python dictionary with repetition of key and value

I have two array as follows:
a=['history','math','history','sport','math']
b=['literature','math','history','history','math']
I zipped two arrays and used dictionary to see if key and values are equal print me them but the dictionary did not print the cases which are repeated, it print only one one them and i need all of them because I need the number of time they are repeated.
My code:
combined_dict={}
for k , v in zip(a,b):
combined_dict[k]=v
print(combined_dict)
In dictionaries, there are no duplicate keys. So when you have {'history':'literature'} after the first loop, it will get overriden with {'history':'history'}.
Instead of creating a dictionary, why not just loop through the zip(a, b)?
for k, v in zip(a, b):
if k == v:
print(k, v)
If you want to have multiple values for one key, then you can use a defaultdict from the collections module:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for k, v in zip(a, b):
... d[k].append(v)
...
>>> print(d)
defaultdict(<type 'list'>, {'sport': ['history'], 'math': ['math', 'math'], 'history': ['literature', 'history']})
>>> print(list(d.items()))
[('sport', ['history']), ('math', ['math', 'math']), ('history', ['literature', 'history'])]
>>> for k, v in d.items():
... if k in v:
... print k, v
...
math ['math', 'math']
history ['literature', 'history']
A dict cannot have the same key for two entries. For multiple values with same key, you need a dict with a list as value.
Try this:
from collections import defaultdict
a=['history','math','history','sport','math']
b=['literature','math','history','history','math']
combined_dict = defaultdict(list)
for k, v in zip(a,b):
combined_dict[k].append(v)
print combined_dict
If you want to get a list of all the items, where there is a match between the two lists, try
>>> print [k for k, v in zip(a, b) if k == v]
['math', 'history', 'math']
This gives you a list of matching items, which you can then process further.

Find a string as value in a dictionary of dictionaries and return its key

I need to write a function which is doing following work
Find a string as value in a dictionary of dictionaries and return its key
(1st key if found in main dictionary, 2nd key if found in sub dictionary).
Source Code
Here is the function which I try to implement, but it works incorrect as I can't find any answer of how to convert list into dictionary as in this case the following error occurs
for v, k in l:
ValueError: need more than 1 value to unpack
def GetKeyFromDictByValue(self, dictionary, value_to_find):
""""""
key_list = [k for (k, v) in dictionary.items() if v == value_to_find]
if key_list.__len__() is not 0:
return key_list[0]
else:
l = [s for s in dictionary.values() if ":" in str(s)]
d = defaultdict(list)
for v, k in l:
d[k].append(v)
print d
dict = {'a': {'a1': 'a2'}, "aa": "aa1", 'aaa': {'aaa1': 'aaa2'}}
print GetKeyFromDictByValue(dict, "a2")
I must do this on Python 2.5
You created a list of only the dictionary values, but then try to loop over it as if it already contains both keys and values of those dictionaries. Perhaps you wanted to loop over each matched dictionary?
l = [v for v in dictionary.values() if ":" in str(v)]
d = defaultdict(list)
for subdict in l:
for k, v in subdict.items():
I'd instead flatten the structure:
def flatten(dictionary):
for key, value in dictionary.iteritems():
if isinstance(value, dict):
# recurse
for res in flatten(value):
yield res
else:
yield key, value
then just search:
def GetKeyFromDictByValue(self, dictionary, value_to_find):
for key, value in flatten(dictionary):
if value == value_to_find:
return key
Demo:
>>> sample = {'a': {'a1': 'a2'}, "aa": "aa1", 'aaa': {'aaa1': 'aaa2'}}
>>> GetKeyFromDictByValue(None, sample, "a2")
'a1'

Simple syntax error in Python if else dict comprehension

I have a set and dictionary and a value = 5
v = s = {'a', 'b', 'c'}
d = {'b':5 //<--new value}
If the key 'b' in dictionary d for example is in set s then I want to make that value equal to the new value when I return a dict comprehension or 0 if the key in set s is not in the dictionary d. So this is my code to do it where s['b'] = 5 and my new dictionary is is ...
{'a':0, 'b':5, 'c':0}
I wrote a dict comprehension
{ k:d[k] if k in d else k:0 for k in s}
^
SyntaxError: invalid syntax
Why?! Im so furious it doesnt work. This is how you do if else in python isnt it??
So sorry everyone. For those who visited this page I originally put { k:d[k] if k in v else k:0 for k in v} and s['b'] = 5 was just a representation that the new dictionary i created would have a key 'b' equaling 5, but it isnt correct cus you cant iterate a set like that.
So to reiterate v and s are equal. They just mean vector and set.
The expanded form of what you're trying to achieve is
a = {}
for k in v:
a[k] = d[k] if k in d else 0
where d[k] if k in d else 0 is the Python's version of ternary operator. See? You need to drop k: from the right part of the expression:
{k: d[k] if k in d else 0 for k in v} # ≡ {k: (d[k] if k in d else 0) for k in v}
You can write it concisely like
a = {k: d.get(k, 0) for k in d}
You can't use a ternary if expression for a name:value pair, because a name:value pair isn't a value.
You can use an if expression for the value or key separately, which seems to be exactly what you want here:
{k: (d[k] if k in v else 0) for k in v}
However, this is kind of silly. You're doing for k in v, so every k is in v by definition. Maybe you wanted this:
{k: (d[k] if k in v else 0) for k in d}
In [82]: s = {'a', 'b', 'c'}
In [83]: d = {'b':5 }
In [85]: {key: d.get(key, 0) for key in s}
Out[85]: {'a': 0, 'b': 5, 'c': 0}
This should solve your problem:
>>> dict((k, d.get(k, 0)) for k in s)
{'a': 0, 'c': 0, 'b': 5}

Categories

Resources