How to increment values for each key in dict? - python

In Python, how to iterate a dict and increment values of each key?
D = {k1:1, k2:2}
I want D to be {k1:2, k2:3}.

You can use a dict comprehension to increment each value, then assign it back
>>> {k: v+1 for k,v in D.items()}
{'k1': 2, 'k2': 3}

You can either modify (also called "mutate") the dictionary D:
for k in D.keys():
D[k] = D[k] + 1
Or you can create a new dictionary and re-assign D to it:
D = { k: v+1 for k, v in D.items() }
The difference will become apparent if something else points at D, or if D is very large and takes longer to re-create than to update in-place.

D = {"k1":1, "k2":2}
for i in D:
D[i] += 1
print(D)
Seems to do the trick, I wasnt sure on the k1 / k2 so i made them strings for testing

I have another solution for you, I hope it is useful.
for key in D:
D[key] +=1

Related

compare values from a list with values from a dictionary

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}

Reversing the key values in a dictionary (advanced reverse string in Python)

So what I was trying to do was output the string "33k22k11k", which is just the last value followed by the reversed last key followed by the second last value followed by the second last reversed key and so on. I'm not sure how to get the reversed key value for the specific loop that I am in. From the code I currently I have, I get the output:
dict = {"k1":1, "k2":2, "k3":3}
current=""
current_k=""
for k,v in dict.items():
for i in k:
current_k=i+current_k
current=str(v)+current_k+current
print(current)
print(current_k)
33k2k1k22k1k11k
3k2k1k
Edited
First of all, if you are on python < 3.6, dict does not keep the order of items. You might want to use collections.OrderedDict for your purpose.
d = {"k1":1, "k2":2, "k3":3}
d.keys()
# dict_keys(['k2', 'k1', 'k3'])
whereas,
d = OrderedDict()
d['k1'] = 1
d['k2'] = 2
d['k3'] = 3
d.keys()
# odict_keys(['k1', 'k2', 'k3'])
With our new d, you can either add the key and values and reverse it:
res = ''
for k, v in d.items():
res += str(k) + str(v)
res[::-1]
# '33k22k11k'
or reversely iterate:
res = ''
for k, v in reversed(d.items()):
res += str(v)[::-1] + str(k)[::-1]
res
# '33k22k11k'
I may be wrong but it seems like you would want to reset the value of current_k each time you access a new key
dict = {"k1":1, "k2":2, "k3":3}
current=""
for k,v in dict.items():
current_k=""
for i in k:
current_k=i+current_k
current=str(v)+current_k+current
print(current)
print(current_k)
Why not simply do:
print(''.join([a+str(b) for a,b in dict.items()])[::-1])
Output:
"33k22k11k"
But if the values are different from the keys, do:
print(''.join([str(b)[::-1]+a for a,b in dict.items()[::-1]]))
You can use the Python map function to create the reversed string(using f-string) for each key/value pair and then join it.
dict1 = {"k1":1, "k2":2, "k3":3}
new_dict = "".join(map(lambda k, v: f'{k}{v}'[::-1] , dict1.keys(), dict1.values()))
Output:
33k22k11k
You can do something like this perhaps:
dict = {"k1":1, "k2":2, "k3":3}
print("".join(list(reversed([str(v)+"".join(reversed(k)) for k, v in dict.items()]))))
Output:
33k22k11k

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.

How to make in-place changes to values between two dictionaries provided the value in dictionary1 is the same as Key in dictionary2?

I have two dictionaries, the first is a dictionary of dictionaries.
dict = {k1:{kk1:vv1, kk2: vv2}, k2:{kkk1:vvv1, kkk2:vvv2}}
dict1 = dict['k2']
# So basically:
# dict1 = {kkk1:vvv1, kkk2:vvv2}
dict3 = {vvv1:actualv1, vvv2:actualv2}
I want the end result to be:
dict1 = {kkk1:actualv1, kkk2:actualv2}
Which is basically:
dict = {k1:{kk1:vv1, kk2: vv2}, k2:{kkk1:actualv1, kkk2:actualv2}}
So, I have tried dictionary comprehension:
{k: dict2.get(v, v) for k, v in dict1.items()}
But to no avail. I have tried to be as clear as possible. One more thing I'd like to mention is that The 'dict' contains about 400 k-v pairs. I have given an example of what I would like to achieve. Help.
Patching the dict1 alone and inplace, accordint to dict3, can be done like this:
d = dict(k1=dict(kk1='vv1', kk2='vv2'),
k2=dict(kkk1='vvv1', kkk2='vvv2'))
dict1 = d['k2']
dict3 = dict(vvv1='actualv1', vvv2='actualv2')
for k in dict1:
v = dict1[k]
try:
dict1[k] = dict3[v]
except KeyError:
pass
print d
prints:
{'k2': {'kkk2': 'actualv2', 'kkk1': 'actualv1'},
'k1': {'kk1': 'vv1', 'kk2': 'vv2'}}
You can try this:
dict = {'k1':{'kk1':'vv1', 'kk2': 'vv2'}, 'k2':{'kkk1':'vvv1', 'kkk2':'vvv2'}}
dict3 = {'vvv1':'actualv1', 'vvv2':'actualv2'}
final_data = {a:{c:dict3.get(d, d) for c, d in b.items()} for a, b in dict.items()}
Output:
{'k1': {'kk1': 'vv1', 'kk2': 'vv2'}, 'k2': {'kkk1': 'actualv1', 'kkk2': 'actualv2'}}
Ok, so you want to process a sub dict from a dict of dicts, given its key, and replace values according to a replacement dict original_value => replacement_value.
You can just do it:
def patch_dic(dic, key, dict3):
for k,v in dic[key].items(): # iterate the sub dict
for orig, repl in dict3.items(): # iterate the replacement dict
if v == orig: # if a value exists in the replacement dict
dic[key][k] = repl # just replace it
Demo:
>>> dic = {'k1':{'kk1':'vv1', 'kk2': 'vv2'}, 'k2':{'kkk1':'vvv1', 'kkk2':'vvv2'}}
>>> patch_dic(dic, 'k2', {'vvv1':'actualv1', 'vvv2':'actualv2'})
>>> print(dic)
{'k1': {'kk1': 'vv1', 'kk2': 'vv2'}, 'k2': {'kkk1': 'actualv1', 'kkk2': 'actualv2'}}

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