I'm doing a project but there's one problem I've run into while using the dictionary, more specifically how to add an entry
thing = {'a':1, 'b':2, 'c':3}
thing.update(input('add more'))
print(thing)
The problem I get when I try to add to this is:ValueError: dictionary update sequence element #0 has length 1; 2 is required. So what way do I have to put the information in so that the dictionary gets updated? So far I tried "d [4]", "d 4" and "d:4".
You must convert your input to be a dictionary by using the curly braces ({ }). You can split the input so that you have a string that contains your key and a string that contains your value.
For example if you wanted to add the string input which was assigned the value d:4 you would use:
key, val = your_input.split(':')
thing.update({key:val})
This is because the dict.update function requires a dictionary as a parameter.
You haven't described what is acceptable for the user to enter, however, you can do it with ast.literal_eval(). This requires the user to enter a valid Python dictionary.
>>> from ast import literal_eval
>>> thing = {'a':1, 'b':2, 'c':3}
>>> thing.update(literal_eval(input('add more: ')))
add more: {'d':4, 'e':5, 'z':26}
>>> thing
{'a': 1, 'c': 3, 'z': 26, 'd': 4, 'b': 2, 'e': 5}
The input is not very user friendly though.
You could just have the user enter space separated keys and values, e.g. a 1 e 5 z 26. Then convert that to a dict and perform the update:
>>> thing = {'a':1, 'b':2, 'c':3}
>>> it = iter(input('add more: ').split())
add more: a 10 y 25
>>> thing.update(dict(zip(it, it)))
>>> thing
{'y': '25', 'c': 3, 'b': 2, 'a': '10'}
Or you could use : to separate keys and values, with space between each item:
>>> thing = {'a':1, 'b':2, 'c':3}
>>> thing.update(dict(s.split(':') for s in input('add more: ').split()))
add more: a:10 z:26
>>> thing
{'a': '10', 'c': 3, 'z': '26', 'b': 2}
If your goal is to add a single element, you can do something like this:
thing['d'] = 4
Substitute the input in the suitable place.
dictionary = {'Big brother':'Onii-chan', 'Big sister': 'Onee-sama', 'Hello': 'Konichiwa', 'Master': 'Sensei', 'Good Morning': 'Ohayo', 'Senior': 'Senpai', 'Ocean': 'Kaiyou/Umi','Darkness': 'Yami', 'Light': 'Hikari', 'Sky':'Sora','x':[1,2]}
keep_going = 'Y'
while keep_going == 'y' or keep_going == 'Y':
print(dictionary.keys())
x = input("Pick one out of the list to see the translation in japanese")
print(dictionary[x])
keep_going = input('would you like another one? (Y for Yes): ')
Related
Let's say I have a dictionary:
data = {'a':1, 'b':2, 'c': 3, 'd': 3}
I want to get the maximum value(s) in the dictionary. So far, I have been just doing:
max(zip(data.values(), data.keys()))[1]
but I'm aware that I could be missing another max value. What would be the most efficient way to approach this?
Based on your example, it seems like you're looking for the key(s) which map to the maximum value. You could use a list comprehension:
[k for k, v in data.items() if v == max(data.values())]
# ['c', 'd']
If you have a large dictionary, break this into two lines to avoid calculating max for as many items as you have:
mx = max(data.values())
[k for k, v in data.items() if v == mx]
In Python 2.x you will need .iteritems().
You could try collecting reverse value -> key pairs in a defaultdict, then output the values with the highest key:
from collections import defaultdict
def get_max_value(data):
d = defaultdict(list)
for key, value in data.items():
d[value].append(key)
return max(d.items())[1]
Which Outputs:
>>> get_max_value({'a':1, 'b':2, 'c': 3, 'd': 3})
['c', 'd']
>>> get_max_value({'a': 10, 'b': 10, 'c': 4, 'd': 5})
['a', 'b']
First of all, find what is the max value that occurs in the dictionary. If you are trying to create a list of all the max value(s), then try something like this:
data = {'a':1, 'b':2, 'c': 3, 'd': 3}
max_value = data.get(max(data))
list_num_max_value = []
for letter in data:
if data.get(letter) == max_value:
list_num_max_value.append(max_value)
print (list_num_max_value)
Please let me know if that's not what you are trying to do and I will guide you through the right process.
I have a Dictionary here:
dic = {'A':1, 'B':6, 'C':42, 'D':1, 'E':12}
and a list here:
lis = ['C', 'D', 'C', 'C', 'F']
What I'm trying to do is (also a requirement of the homework) to check whether the values in the lis matches the key in dic, if so then it increment by 1 (for example there's 3 'C's in the lis then in the output of dic 'C' should be 45). If not, then we create a new item in the dic and set the value to 1.
So the example output should be look like this:
dic = {'A':1, 'B':6, 'C':45, 'D':2, 'E':12, 'F':1}
Here's what my code is:
def addToInventory(dic, lis):
for k,v in dic.items():
for i in lis:
if i == k:
dic[k] += 1
else:
dic[i] = 1
return dic
and execute by this code:
dic = addToInventory(dic,lis)
It compiles without error but the output is strange, it added the missing F into the dic but didn't update the values correctly.
dic = {'A':1, 'B':6, 'C':1, 'D':1, 'E':12, 'F':1}
What am I missing here?
There's no need to iterate over a dictionary when it supports random lookup. You can use if x in dict to do this. Furthermore, you'd need your return statement outside the loop.
Try, instead:
def addToInventory(dic, lis):
for i in lis:
if i in dic:
dic[i] += 1
else:
dic[i] = 1
return dic
out = addToInventory(dic, lis)
print(out)
{'A': 1, 'B': 6, 'C': 45, 'D': 2, 'E': 12, 'F': 1}
As Harvey suggested, you can shorten the function a little by making use of dict.get.
def addToInventory(dic, lis):
for i in lis:
dic[i] = dic.get(i, 0) + 1
return dic
The dic.get function takes two parameters - the key, and a default value to be passed if the value associated with that key does not already exist.
If your professor allows the use of libraries, you can use the collections.Counter data structure, it's meant precisely for keeping counts.
from collections import Counter
c = Counter(dic)
for i in lis:
c[i] += 1
print(dict(c))
{'A': 1, 'B': 6, 'C': 45, 'D': 2, 'E': 12, 'F': 1}
I have a bunch of files I'm creating dictionaries from and in some of the files the key and value I'm creating are identical. I need to keep track of the dictionaries that are identical so another person can update them with the right values. I'd like to set the value for these dictionaries to none. I've already stripped all whitespaces and weird characters so the key and value are exactly identical. I basically want to say, "if the key and value are identical, then set value = None"...
x = file I'm creating dictionary from
if x[1] = x[4]:
d[x[1]] = None
But whenever do anything like this I get a an error message:
SyntaxError: invalid syntax
Any suggestions?
As i can't understand the description properly, i will answer the title :
for k, v in d.items():
if k == v:
d[k] = None
You can use a dictionary comprehension for this:
>>> d = { 'a': 1, 'b': 2, 'c': 'c' }
>>> { a: None if a == b else b for a,b in d.items() }
{'a': 1, 'c': None, 'b': 2}
This obviously will create a copy of the whole dictionary, so the above answers are probably better for your use case.
In Python (and in all other languages I know), for comparing the value in if, double equals == is used. I'll suggest you to read: Python IF...ELIF...ELSE Statements. Below is the sample code, to set value as None where key and value are same:
my_dict = {'a': '1', 'b': 'b', 'c': '2', 'd': 'd'} # 'b' and 'c' have same
# 'key' and 'value'
for key, value in my_dict.items():
if key == value:
my_dict[key] = None
# Updated value of 'my_dict':
# {'a': '1', 'c': '2', 'b': None, 'd': None}
I may have understood this wrong but looking at the examples found in "Learning Python" by O'Reilly I tried to do the following:
>>> d={}
>>> d['h']='GG'
>>> d['f']='JJ'
>>> d['h']='PP'
>>> print d
{'h': 'PP', 'f': 'JJ'}
Now instead of the 'key' 'h' having two entries 'GG' and 'PP' it only has the last entry, the last one replacing the first one.
I want BOTH in the same key.
>>> d['h']+='RR'
>>> print d
{'h': 'PPRR', 'f': 'JJ'}
Again this doesn't work, what I wanted was not a concatenated string but comma-separated entires.
I am confused why this does not work.
Your use-case is handled nicely by the collections.defaultdict() type instead:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d['h'].append('GG')
>>> d['f'].append('JJ')
>>> d['h'].append('PP')
>>> d
defaultdict(<type 'list'>, {'h': ['GG', 'PP'], 'f': ['JJ']})
A regular dictionary maps one key to one value, if you want that value to be a list, then you should make it a list, and append to the list instead.
You don't have to use a defaultdict() object, you can always make your values explicit lists:
>>> d = {}
>>> d['h'] = ['GG']
>>> d['f'] = ['JJ']
>>> d['h'].append('PP')
>>> print d
{'h': ['GG', 'PP'], 'f': ['JJ']}
but now you need to create the lists explicitly. The latter problem can then be circumvented again by using dict.setdefault():
>>> d = {}
>>> d.setdefault('h', []).append('GG')
>>> d.setdefault('f', []).append('JJ')
>>> d.setdefault('h', []).append('PP')
which is just a more verbose way of using what defaultdict() objects can provide directly.
It sounds like you want your dictionary to have 'h' map to a list of strings, which you can do as follows:
>>> d={}
>>> d['f']='JJ'
>>> d['h']=['PP']
>>> d['h'].append( 'RR' )
>>> d
{'h': ['PP', 'RR'], 'f': 'JJ'}
If you want all the keys of your dictionary to map to a list (instead of just 'h'), you can use collection.defaultdict as demonstrated in #MartijnPieters's answer.
this is my program on counting the number of vowels
'''Program to count number of vowels'''
str=input("Enter a string\n")
a=0
e=0
i=0
o=0
u=0
for x in str:
if x=='a':
a=a+1
continue
if x=='e':
e=e+1
continue
if x=='i':
i=i+1
continue
if x=='o':
o=o+1
continue
if x=='u':
u=u+1
continue
count={}
if a>0:
count['a']=a
if e>0:
count['e']=e
if i>0:
count['i']=i
if o>0:
count['o']=o
if u>0:
count['u']=u
print(count)
How can I improve the initial loop for comparison along with the process of filling the dictionary.
While running the program several times I have obtained the following output:
>>>
Enter a string
abcdefgh
{'e': 1, 'a': 1}
>>> ================================ RESTART ================================
>>>
Enter a string
abcdefghijklmnopqrstuvwxyz
{'u': 1, 'a': 1, 'o': 1, 'e': 1, 'i': 1}
>>> ================================ RESTART ================================
>>>
Enter a string
abcdeabcdeiopiop
{'a': 2, 'o': 2, 'i': 2, 'e': 2}
From this I could not figure out how exactly are the key value pairs being added to the dictionary count against my expectation of:
Case 1:
{'a':1, 'e':1}
Case 2:
{'a':1, 'e':1, 'i':1, 'o':1, 'u':1}
Case 3:
{'a':2, 'e':2, 'i':2, 'o':2}
Any help is appreciated.
>>> import collections
>>> s = "aacbed"
>>> count = collections.Counter(c for c in s if c in "aeiou")
>>> count
Counter({'a': 2, 'e': 1})
Or - if you really need to maintain insertion order:
>>> s = 'debcaa'
>>> count=collections.OrderedDict((c, s.count(c)) for c in s if c in "aeiou")
>>> count
OrderedDict([('e', 1), ('a', 2)])
Finally if you want lexicographic ordering, you can either turn your dict/counter/ OrderedDict into a list of tuples:
>>> sorted(count.items())
[('a', 2), ('e', 1)]
and if you want a lexicographically OrderedDict:
>>> sorted_count = collections.OrderedDict(sorted(count.items()))
>>> sorted_count
OrderedDict([('a', 2), ('e', 1)])
A more Pythonic way to do what you want is:
'''Program to count number of vowels'''
s = input("Enter a string\n")
count = {v: s.count(v) for v in "aeiou" if s.count(v) > 0}
print(count)
You shouldn't use str as a variable name, as that is the name of the built-in string type.
Just put a=0 e=0 i=0 o=0 u=0 inside a dictionary like that:
myDict = {'a':0, 'e':0, 'i':0, 'o':0, 'u':0}
for x in string:
myDict[x] += 1
print myDict
If the value is not one of the following then a raise of KeyError will come up.
So you can do something like that:
myDict = {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0}
for x in string:
try:
myDict[x] += 1
except KeyError:
continue
print myDict
Note: I've changed the name str to string
You can also see a very good solution by #Amber here