How to update a dictionary in python [closed] - python

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have the following dictionary
>>> {'a':3, 'i': 1, 'k': 1, 'm': 1, 'l': 1, 'n': 1, 'p': 1, 'u': 1}
How can I update it to,
>>> updateDict({'a':3, 'i': 1, 'k': 1, 'm': 1, 'l': 1, 'n': 1, 'p': 1, 'u': 1},
milk),
such that the output is
{'a':3, 'i': 0, 'k': 0, 'm': 0, 'l': 0, 'n': 1, 'p': 1, 'u': 1}
?

To reset the keys in 'milk' to 0:
In [14]: d = {'a':3, 'i': 1, 'k': 1, 'm': 1, 'l': 1, 'n': 1, 'p': 1, 'u': 1 }
In [15]: d.update(dict.fromkeys(list('milk'), 0))
In [16]: d
Out[16]: {'a': 3, 'i': 0, 'k': 0, 'l': 0, 'm': 0, 'n': 1, 'p': 1, 'u': 1}
To decrement the keys in 'milk' by 1, you could use a loop, as in mitchelllc's answer. Or, if you are willing to eliminate keys with values of 0, you could use a collections.Counter like this:
import collections
d = collections.Counter({'a':3, 'i': 1, 'k': 1, 'm': 1, 'l': 1, 'n': 1, 'p': 1, 'u': 1 })
m = collections.Counter(list('milk'))
print(d - m)
yields
Counter({'a': 3, 'p': 1, 'u': 1, 'n': 1})

>>> dict = {'a':3, 'i': 0, 'k': 0, 'm': 0, 'l': 0, 'n': 1, 'p': 1, 'u': 1}
>>> for s in 'milk':
>>> if s in dict:
>>> dict[s] -= 1
If you want to set 'milk' to zero in the dict, see #unutbu's answer.

For each character in the string get the corresponding value from the dictionary, decrement the value, and reinsert it.

Try this:
s = 'milk'
d = {'a':3, 'i': 1, 'k': 1, 'm': 1, 'l': 1, 'n': 1, 'p': 1, 'u': 1 }
for letter in s:
if letter in d:
d[letter] = 0

Related

Get all keys with the same value in a dictionary

I have a dictionary with all the letters and I want to get all the letters (so the keys) that occur the most.
letters = {'A': 0, 'B': 0, 'C': 0, 'D': 0, 'E': 1, 'F': 1, 'G': 1, 'H': 0, 'I': 0, 'J': 0, 'K': 0, 'L': 2, 'M': 4, 'N': 0, 'O': 1, 'P': 1, 'Q': 4, 'R': 0, 'S': 1, 'T': 2, 'U': 2, 'V': 0, 'W': 0, 'X': 1, 'Y': 0, 'Z': 0}
So M and Q are to be output
My Python version is 3.9.2
max_value = max(letters.values())
[key for key, val in letters.items() if val == max_value]

How can I map alphabet as keys and the occurence of the letters as values

I am trying to create a dictionary to map the amount of times a letter appears to the letter of the alphabet, however I want to print the entire alphabet in the dictionary even if a letter does not appear in the list of strings. So i want the alphabet letter to be the key and the amount of times the letter occurs as the value.
The following is my code
import string
from collections import Counter
listy = ["hello","there","I","am","a","string"]
letter_count = dict( (key, 0) for key in string.ascii_lowercase )
print(dict_count)
My expected output should be
{a:2,b:0,c:0,d:0,e:3}
and so on until i reach z
I realize the key value should be something else in the list comprehension, but I simply cannot figure out what. I just don't exactly know what i can do to map the amount of times a letter occurs to the correct letter in my dictionary so I just added 0 there. Would using a dictionary comprehension be better? I am new to dictionaries, and dictionary comprehension, but a friend of mine recommended I should learn it since apparently it is a powerful tool to have so any help would be appreciated
import string
listy = ["hello","there","I","am","a","string"]
concatenated_listy="".join(listy).lower()
letter_count = dict( (key, concatenated_listy.count(key)) for key in string.ascii_lowercase )
letter_count
Answer would be
{'a': 2, 'b': 0, 'c': 0, 'd': 0, 'e': 3, 'f': 0, 'g': 1, 'h': 2, 'i': 2, 'j': 0, 'k': 0, 'l': 2, 'm': 1, 'n': 1, 'o': 1, 'p': 0, 'q': 0, 'r': 2, 's': 1, 't': 2, 'u': 0, 'v': 0, 'w': 0, 'x': 0, 'y': 0, 'z': 0}
You can continue your suggested code with the below to read the letters one by one and add them to a histogram of letters encoded in your Dictionary:
import string
letterHist = dict((key, 0) for key in string.ascii_lowercase)
listy = ["hello","there","I","am","a","string"]
for word in listy:
for letter in word:
letterHist[letter.lower()] += 1
And the above should give you:
{'a': 2, 'b': 0, 'c': 0, 'd': 0, 'e': 3, 'f': 0, 'g': 1, 'h': 2, 'i': 2, 'j': 0, 'k': 0, 'l': 2, 'm': 1, 'n': 1, 'o': 1, 'p': 0, 'q': 0, 'r': 2, 's': 1, 't': 2, 'u': 0, 'v': 0, 'w': 0, 'x': 0, 'y': 0, 'z': 0}
You can use dict.fromkeys:
from string import ascii_lowercase
listy = ["hello","there","I","am","a","string"]
dict_count = dict.fromkeys(ascii_lowercase, 0)
for letter in ''.join(listy).lower():
dict_count[letter] += 1
>>> dict_count
{'a': 2, 'b': 0, 'c': 0, 'd': 0, 'e': 6, 'f': 0, 'g': 1, 'h': 4, 'i': 2, 'j': 0,
'k': 0, 'l': 4, 'm': 1, 'n': 1, 'o': 2, 'p': 0, 'q': 0, 'r': 3, 's': 1, 't': 3,
'u': 0, 'v': 0, 'w': 0, 'x': 0, 'y': 0, 'z': 0}
You could also use collectoins.Counter instead of the for-loop:
>>> dict_count = dict.fromkeys(ascii_lowercase, 0)
>>> dict_count.update(Counter(''.join(listy).lower()))
>>> dict_count
{'a': 2, 'b': 0, 'c': 0, 'd': 0, 'e': 3, 'f': 0, 'g': 1, 'h': 2, 'i': 2, 'j': 0,
'k': 0, 'l': 2, 'm': 1, 'n': 1, 'o': 1, 'p': 0, 'q': 0, 'r': 2, 's': 1, 't': 2,
'u': 0, 'v': 0, 'w': 0, 'x': 0, 'y': 0, 'z': 0}
Note: In this case, most approaches with dictionary comprehension will have poor performance (eg. if you use str.count), so if you need to use dict comprehension try combining it with collections.Counter:
>>> alpha_count = Counter(''.join(listy).lower())
>>> dict_count = {alpha: alpha_count.get(alpha, 0) for alpha in ascii_lowercase}
>>> dict_count
{'a': 2, 'b': 0, 'c': 0, 'd': 0, 'e': 6, 'f': 0, 'g': 1, 'h': 4, 'i': 2, 'j': 0,
'k': 0, 'l': 4, 'm': 1, 'n': 1, 'o': 2, 'p': 0, 'q': 0, 'r': 3, 's': 1, 't': 3,
'u': 0, 'v': 0, 'w': 0, 'x': 0, 'y': 0, 'z': 0}
``
listy = ["hello","there","I","am","a","string"]
alphabet = 'abcdefghijklmnopqrstuvwxyz'
dict1 = {}
#Create a dictionary to store the number of occurrences of each of the 26 letters
#each word initially set to 0
for i in alphabet:
dict1[i] = 0
for j in listy:
for k in j.lower(): # Converted to lowercase
if k in dict1.keys():
dict1[k] = dict1.get(k,0)+1
print(dict1)
``

Check if a Dictionary is a Subset of another Dictionary with Key Value pairs

I have two Dictionaries resources, and available_resources:
resources = {'B': 1, 's': 2, 't': 3, 'e': 3, '!': 1, 'h': 1, 'i': 1, ' ': 3, 'o': 1, 'g': 1, 'E': 1, 'A': 1, 'x': 2, 'p': 1, 'l': 1, 'r': 1}
available_resources = {'A': 1, 'l': 1, 'g': 1, 'o': 1, 'E': 1, 'x': 1, 'p': 1, 'e': 3, 'r': 1, 't': 3, ' ': 3, 'i': 1, 's': 2, 'h': 1, 'B': 1, '!': 1}
I want to check if resources is a subset of available_resources (if each element contained in the dictionary is <= the corresponding value entry in the resources dictionary)
I've tried:
if all(available_resources.get(key, None) == val for key, val
in resources.items()):
return True
It is returning false, is there another way I can get it to work?
Could it be a simple sign error? From "==" val to "<=" val? I got true from the below.
if all(available_resources.get(key, None) <= val for key, val
in resources.items()):
return True
If all the values are integers, one approach is to use collections.Counter:
from collections import Counter
resources = {'B': 1, 's': 2, 't': 3, 'e': 3, '!': 1, 'h': 1, 'i': 1, ' ': 3, 'o': 1, 'g': 1, 'E': 1, 'A': 1, 'x': 2, 'p': 1, 'l': 1, 'r': 1}
available_resources = {'A': 1, 'l': 1, 'g': 1, 'o': 1, 'E': 1, 'x': 1, 'p': 1, 'e': 3, 'r': 1, 't': 3, ' ': 3, 'i': 1, 's': 2, 'h': 1, 'B': 1, '!': 1}
res = bool(Counter(resources) - Counter(available_resources))
print(res)
Output
True
You can use the <= operator from sets. This operator determines whether one set is a subset of the other.
As follows:
>>> resources.items() <= available_resources.items()
False
This returns False as there is a difference between the element x in the different dict. You can see this difference using the set operator ^ with will return you the symmetric difference between the dict:
>>> resources.items() ^ available_resources.items()
{('x', 1), ('x', 2)}
You need to use <= instead of ==
>>> all(available_resources.get(k, -1)<=v for k,v in resources.items())
True
Also, above method may fail if resources contains some key that doesn't exist in available_resources, and you can additionally check if the keys in resources are subset of the keys in available_resources for this condition
>>> all(available_resources.get(k, -1)<=v for k,v in resources.items()) and\
set(resources).issubset(available_resources)
True
I have tested the answers in this stackoverflow question: click here
And i think it's works for you!
all(item in available_resources.items() for item in resources.items())
# - or - #
available_resources.items() <= resources.items()

Count the frequency of letters in a string, not blank spaces, numbers, or punctuation

def count_letters(text):
result = {}
# Go through eactter in the text
for letter in text:
# Check if the letter needs to be counted or not
if letter in text:
result[letter.lower()]=result.get(letter,0)+1
# Add or increment the value in the dictionary
for k in result:
return result
print(count_letters("AaBbCc"))
# Should be {'a': 2, 'b': 2, 'c': 2}
print(count_letters("Math is fun! 2+2=4"))
# Should be {'m': 1, 'a': 1, 't': 1, 'h': 1, 'i': 1, 's': 1, 'f': 1, 'u': 1, 'n': 1}
print(count_letters("This is a sentence."))
# Should be {'t': 2, 'h': 1, 'i': 2, 's': 3, 'a': 1, 'e': 3, 'n': 2, 'c': 1}
You can use Counter with filter.
import string
from collections import Counter
Counter(filter(lambda x:x in string.ascii_letters,_str.lower()))
Counter({'m': 1,
'a': 1,
't': 1,
'h': 1,
'i': 1,
's': 1,
'f': 1,
'u': 1,
'n': 1})

Simultaneously replacing all values of a dictionary to zero python

I have a very large dictionary, maybe about 10,000 keys/values and I want to simultaneously change all values to 0. I am aware that I can loop through and set all the values to 0 but it take forever. Is there anyway that I can simultaneously set all values to 0?
Looping method, very slow:
# example dictionary
a = {'a': 1, 'c': 1, 'b': 1, 'e': 1, 'd': 1, 'g': 1, 'f': 1, 'i': 1, 'h': 1, 'k': 1,
'j': 1, 'm': 1, 'l': 1, 'o': 1, 'n': 1, 'q': 1, 'p': 1, 's': 1, 'r': 1, 'u': 1,
't': 1, 'w': 1, 'v': 1, 'y': 1, 'x': 1, 'z': 1}
for key, value in a.items():
a[key] = 0
Output:
{'a': 0, 'c': 0, 'b': 0, 'e': 0, 'd': 0, 'g': 0, 'f': 0, 'i': 0, 'h': 0, 'k': 0,
'j': 0, 'm': 0, 'l': 0, 'o': 0, 'n': 0, 'q': 0, 'p': 0, 's': 0, 'r': 0, 'u': 0,
't': 0, 'w': 0, 'v': 0, 'y': 0, 'x': 0, 'z': 0}
You want dict.fromkeys():
a = dict.fromkeys(a, 0)
Thanks #akaRem for his comment :)
a = dict.fromkeys( a.iterkeys(), 0 )
Be warned, if the order of your keys matter the solution may not be suitable as it seems to reorder.
To stop this from happening use list comprehension:
aDictionary = { x:0 for x in aDictionary}
Note: It's only 2.7.x and 2.x exclusive
To expand on #Daniel Roseman answer a=a.fromkeys(d,0) is functionaly the same and a bit faster. Also if you plan to do this frequently save=dict.fromkeys(a,0) and then call a=save.copy() which is faster in some cases(large dicts)

Categories

Resources