A basic operation of python's dictionary - python

encoder.load_state_dict({k:v for k,v in encoder_dict.items() if k in model_dict})
This syntax is an operation of the dictionary, but I can't understand that what does "k:v" acts?

encoder.load_state_dict({k:v for k,v in encoder_dict.items() if k in model_dict})
This is dictionary comprehension. An equivalent code in simple terms would be:
new_dict = dict()
for k,v in encoder_dict.items():
if k in model_dict:
new_dict[k] = v
encoder.load_state_dict(new_dict)
where k and v corresponds to the key and value pair returned by encoder_dict.items()

Related

Adding additional logic to a lambda function to get the minimum value from a python dictionary

I have a dictionary with values mapping some object to an integer; e.g. {node: 1, node: 2}.
I want to get the key that corresponds to the minimum value in this dictionary, which I know I can do with:
min_key = min(my_dict, key=lambda k: my_dict[k])
However, I'd also like to add the constraint that the key is not contained within some other set. Here's the pseudo-code that I wished worked:
min_key = min(my_dict, key=lambda k: my_dict[k] where k not in my_set)
Is there a way to write this as a one-liner in python as part of a lambda, or do I now have to explicitly loop through the dictionary and add the logic within the loop like this?
min_key, min_value = None, float('inf')
for k,v in my_dict.items():
if v < min_value and k not in my_set:
min_key = k
return min_key
Replace my_dict with a dictionary comprehension that returns the filtered dictionary.
min_key = min({k:v for k, v in my_dict.items() if k not in my_set},
key = lambda k: my_dict[k])
Just take the minimum over the filtered keys instead of all keys:
min_key = min(my_dict.keys() - my_set, key=my_dict.get)
(Note I also replaced your key function, no need to write your own.)
It's similar to #Barmar's answer but you can also use set.difference between my_dict and my_set to filter the relevant dictionary:
out = min(set(my_dict).difference(my_set), key = lambda k: my_dict[k])

Get averages from a dictionary in Python

Get averages from a python dictionary for example if i have the next dictionary:
students={'Dan':(5,8,8), 'Tim':(7), 'Richard':(9,9)}
And i would like to print de dictionary in the next form:
results={'Dan':(7), 'Tim':(7), 'Richard':(9)}
is there any function that i can use? Im new coding in python so dictionaries are a bit confusing for me.
If you want that the avg values will be a tuple element (I don't see any reason to do so but maybe I don't have enough context), try:
results={k: (sum(v)/len(v),) for k,v in students.items()}
I'd do:
result = {}
for k, v in students.items():
if type(v) in [float, int]:
result[k] = v
else:
result[k] = sum(v) / len(v)
I was trying this but realized we had a problem summing a tuple of length 1. So you can do it this way.
results = {}
for k, v in students.items():
print(v)
if (isinstance(v, int)):
results[k] = v
else:
results[k] = sum(v) / len(v)
A pythonic solution would be to use dictionary comprehension to create the results dictionary.
def avg(l):
return sum([l]) / len(l)
results = {key: (avg(val)) for (key, val) in students.items()}
You need brackets around the l in sum so the tuple is treated as a list. I would further change the data structure to a list instead of tuple.

Check if value exists in a dictionary of dictionaries and get the key(s)?

I have a dictionary of dictionaries:
x = {'NIFTY': {11382018: 'NIFTY19SEPFUT', 13177346: 'NIFTY19OCTFUT', 12335874: 'NIFTY19NOVFUT'}}
The dictionary has a lot of other dictionaries inside.
I want to check whether example:
y = 11382018
exists in the dictionary, if yes, get the master key in this case NIFTY and the value of the above key i.e. 'NIFTY19SEPFUT'
I can do this in the following way I assume:
for key in x.keys():
di = x[key]
if y in di.keys():
inst = key
cont = di[y]
Just wondering if there is a better way.
I was thinking along the lines of not having to loop over the entire dictionary master keys
A more compact way to retrieve both values of interest would be using a nested dictionary comprehension:
[(k, sv) for k,v in x.items() for sk,sv in v.items() if sk == y]
# [('NIFTY', 'NIFTY19SEPFUT')]
More compact version (generic):
[(k, v[y]) for k, v in d.items() if y in v]
Or:
*next(((k, v[y]) for k, v in d.items() if y in v), 'not found')
if you can guarantee the key is found only in one nested dictionary. (Note that I have used d as dictionary here, simply because that feels more meaningful)
Code:
d = {'NIFTY': {11382018: 'NIFTY19SEPFUT', 13177346: 'NIFTY19OCTFUT', 12335874: 'NIFTY19NOVFUT'}}
y = 11382018
print([(k, v[y]) for k, v in d.items() if y in v])
# or:
# print(*next(((k, v[y]) for k, v in d.items() if y in v), 'not found'))
Straightforwardly (for only 2 levels of nesting):
x = {'NIFTY': {11382018: 'NIFTY19SEPFUT', 13177346: 'NIFTY19OCTFUT', 12335874: 'NIFTY19NOVFUT'}}
search_key = 11382018
parent_key, value = None, None
for k, inner_d in x.items():
if search_key in inner_d:
parent_key, value = k, inner_d[search_key]
break
print(parent_key, value) # NIFTY NIFTY19SEPFUT

How to split list inside a dictionnary to create a new one?

I've been struggling on something for the day,
I have a dictionnary under the format
dict = {a:[element1, element2, element3], b:[element4, element5, element6]...}
I want a new dictionnary under the form
newdict = {a:element1, b:element4...}
Meaning only keeping the first element of the lists contained for each value.
You can use a dictionary comprehension:
{k: v[0] for k, v in d.items()}
# {'a': 'element1', 'b': 'element4'}
Hopefully this helps.
I like to check if the dictionary has a key before overwriting a keys value.
dict = {a:[element1, element2, element3], b:[element4, element5, element6]}
Python 2
newDict = {}
for k, v in dict.iteritems():
if k not in newDict:
# add the first list value to the newDict's key
newDick[k] = v[0]
Python 3
newDict = {}
for k, v in dict.items():
if k not in newDict:
# add the first list value to the newDict's key
newDick[k] = v[0]

Iterate over a list of objects getting ke/value pairs

I'd like to iterate over a list of objects (where I don't know their keys) in as simple way as possible, without creating unnecessary temp variables.
So let's say that's my array :
y = [{'faz': 'baz'}, {'foo': 'bar'}]
Getting k, v from object can be easily done with iteritems() but is it possible to iterate over list using lambda at the same time ?
EDIT
Pseudocode:
for k, v in x where x is an array item
if your keys are unique across the list, you can do:
for k, v in {k:v for l in y for k, v in l.iteritems()}.iteritems():
print k, v
or equivalently,
y2 = {k:v for l in y for k, v in l.iteritems()}
for k, v in y2.iteritems():
print k, v
but it is not very pretty.
If all your dict have one one key-value pair, you can do this:
for k,v in map(lambda x: x.items()[0], y):
print k, v
Another solution is the following which just iterates over the list and then over the dict:
def items(lis):
for l in lis:
for k, v in l.iteritems():
yield k, v
for k, v in items(y):
print k, v

Categories