Adding to dictionary keys - python

I'm trying to create a running leaderboard in which each person starts with one point and I add to the key if they accomplish something. I'm not certain a dictionary is the best way to do it so recommendations are definitely welcomed.
I tried a list to begin with but a dictionary seemed to better suit my needs as I had lists inside of lists
myDict = {'person1' : 1 , 'person2' : 1 , 'person3' : 1}
If person1 were to do something i'd like their key to change to 2. I need to increment the keys, not assign a specific key. Also I will continually add entries to the dict for which I need their default value to be 1.
edit: Chris had a super helpful suggestion to use collections.defaultdict so that calling key that isn't in a dict adds it instead of returning a keyerror

A value can be added or changed or reassigned in a python dictionary by simply accessing through it's key
myDict[key] = value
In your case:
myDict["person1"] = 2 # Reassignment or changing
myDict["person1"] += 1 # Increementing
If the key doesn't exist, incrementing will be a problem. In that scenario, you need to check if the key is present or not.
if myDict["person5"]:
myDict["person5"] += 1
else:
myDict["person5"] = 1
Reference https://docs.python.org/3/tutorial/datastructures.html#dictionaries

Unless you want to do something like sorting players by scores at the end, a dictionary seems a good option. (You can do the sorting but have to have a workaround since dictionary is only indexed by its keys)
Otherwise you can do the following to update the scores
myDict = {}
person = '<person_name>'
# in case the person did something
if person in myDict:
myDict[person] += 1
else:
myDict[person] = 1

You can update a dictionary as follows:
>>> myDict = {'person1': 1, 'person2': 1}
>>> myDict['person7'] = 2
You may also want to investigate
import collections
myDict = collections.defaultdict(lambda: 1)
myDict['person7'] += 1
as this will automatically initialize unset values to 1 the first time they are read.

Related

Immutability of dictionary keys in python

dic={}
dic[1]=100
dic[2]=200
dic[1]+=500
here I have initialed a dictionary and I am able to update the key value of the dictionary. But keys in dictionary are immutable, so what's actually happening , can someone please tell?
Just think of it this way. We have an empty dictionary:
d = {}
If we do this:
d[1] = 100
we are simply adding a key and assigning a value to that key, right then and there.
Just like sets, dicts cannot have duplicate keys, so adding another key with the same name will overwrite the original.
Like doing calling d[1] = 200 will overwrite the original d[1].
d[1] += 500 is the same as:
d[1] = d[1]+500
where we are simply telling python to add a key to d called 1, and assign the value of the original key plus 500 to that key.

How do you delete a key from a dictionary by only using an value entered by a user

I am a student trying to complete a task on a online course and I can't find a efficient way to solve this problem.
problem:
Ask the user to enter 4 of their favorite foods and store them in a dictionary so that they are indexed with numbers starting from 1. Display the dictionary in full showing the index number an the item. Ask them which they want to get rid of and remove it from the list. Sort the remaining data and display it.
I have tried many possible solutions but none of them seem to work. This is what i have done so far (python 3.8):
foodcount=0
foods={1:0 ,2:0 ,3:0 ,4: 0}
while foodcount<4:
food_choice=str(input('enter one of your favourite foods'))
foodcount += 1
foods[foodcount] = food_choice
least_fav=str(input('choos a food to delete'))
nowant=foods.index[least_fav]
del foods[nowant]
print(foods)
foods.sort(key=str)
for key,value in foods:
print(foods(key,value))
I am not sure if I am misinterpreting this question but the main problem I am having is once the user enters the food they would like to delete (assume that the always enters a input that is in the dict) I can't delete the key the the food is in (can't delete the key and value). I know i have to index something but still really not sure
Thanks in advance
dict does not support .index so you are going to have to use a for loop to iterate through a dictionary.
foodcount=0
foods={1:0 ,2:0 ,3:0 ,4: 0}
while foodcount<4:
food_choice=str(input('enter one of your favourite foods'))
foodcount += 1
foods[foodcount] = food_choice
least_fav=str(input('choose a food to delete'))
for key, value in foods.items():
if value == least_fav:
foods.pop(key)
break
print(foods)
for key,value in foods.items():
print(key,value)
you already showed you know how to use a for loop to loop through the dictionary but you have to change it up a bit. If you use "foods" in a for loop it will only iterate through the keys, so 1, 2, 3, 4. if you use "foods.items()" it sets key to the keys and value to the values, which I assume you wanted.
Next you just tell it that if the value of a key is the same as what the user entered you use .pop which deletes a key:value pair based on the value.
other than that you just make sure you break when you are done so you don't get an error and use your (revised) print loop at the bottom to get the keys and values.
Hope this helps!
If your dictionary has the foods as keys it is easier to work with them. This will work even if they misswrite the name (won't happen anything if they write it wrong):
foodcount=0
foods = []
while foodcount<4:
food_choice=str(input('enter one of your favourite foods'))
foodcount += 1
foods.append(food_choice)
foods_dict = dict(zip(foods,[1,2,3,4]))
least_fav=str(input('choos a food to delete'))
foods_dict.pop(least_fav, None)
Output:
Foods: a,b,c,d
Least favorite: b
print(foods_dict)
{'a': 1, 'c': 3, 'd': 4}

Why does the default dictionary in my code keep expanding?

I have a default dictionary and I run it through a couple of loops to look for certain strings in the dictionary. The loops don't really append anything to the dictionary yet as it turns out, during the loop, new items keep getting appended to the dictionary and the final dictionary ends up bigger than the original one before the loop.
I've been trying to pinpoint the error forever but now it's late and I have no idea what's causing this!
from collections import defaultdict
dummydict = defaultdict(list)
dummydict['Alex'].append('Naomi and I love hotcakes')
dummydict['Benjamin'].append('Hayley and I hate hotcakes')
part = ['Alex', 'Benjamin', 'Hayley', 'Naomi']
emp = []
for var in dummydict:
if 'I' in dummydict[var]:
emp.append(var)
for car in part:
for key in range(len(dummydict)):
print('new len', len(dummydict))
print(key, dummydict)
if car in dummydict[key]:
emp.append(car)
print(emp)
print('why are there new values in the dictionary?!', len(dummydict), dummydict)
I expect the dictionary to remain unchanged.
if car in dummydict[key]:
key being an integer, and your dict being initially filled with only string as keys, this will create a new value in dummydict for each key.
Accessing missing keys as in dummydict[key] will add those keys to the defaultdict. Note that key is an int, not the value at that position, as for key in range(len(dummydict)) iterates indexes, not the dict or its keys.
See the docs:
When each key is encountered for the first time, it is not already in the mapping; so an entry is automatically created using the default_factory function which returns an empty list.
For example, this code will show a dummydict with a value in it, because simply accessing dummydict[key] will add the key to the dict if that key is not already there.
from collections import defaultdict
dummydict = defaultdict(list)
dummydict[1]
print (dummydict)
outputs:
defaultdict(<class 'list'>, {1: []})
Your issue is that in your loop, you do things like dummydict[key] and dummydict[var], which adds those keys.

Updating a dictionary with integer keys

I'm working on a short assignment where I have to read in a .txt file and create a dictionary in which the keys are the number of words in a sentence and the values are the number of sentences of a particular length. I've read in the file and determined the length of each sentence already, but I'm having troubles creating the dictionary.
I've already initialized the dictionary and am trying to update it (within a for loop that iterates over the sentences) using the following code:
for snt in sentences:
words = snt.split(' ')
sDict[len(words)]+=1
It gives me a KeyError on the very first iteration. I'm sure it has to do with my syntax but I'm not sure how else to update an existing entry in the dictionary.
When you initialize the dictionary, it starts out empty. The next thing you do is look up a key so that you can update its value, but that key doesn't exist yet, because the dictionary is empty. The smallest change to your code is probably to use the get dictionary method. Instead of this:
sDict[len(words)]+=1
Use this:
sDict[len(words)] = sDict.get(len(words), 0) + 1
The get method looks up a key, but if the key doesn't exist, you are given a default value. The default default value is None, and you can specify a different default value, which is the second argument, 0 in this case.
The better solution is probably collections.Counter, which handles the common use case of counting occurrences:
import collections
s = map(str.split, sentences)
sDict = collections.Counter(map(len, s))
defaultdicts were invented for this purpose:
from collections import defaultdict
sDict = defaultdict(int)
for snt in sentences:
sDict[len(snt.split())] += 1
If you are restricted to the use of pure dictionaries in the context of your assignment, then you need to test for existence of the key before incrementing its value in order to prevent a KeyError:
sDict = {}
for snt in sentences:
num_words = len(snt.split())
if num_words in sDict:
sDict[num_words] += 1
else:
sDict[num_words] = 1

How to make a list of dicts with nested dicts

I am not sure if thats what i really want but i want this structure basically,
-document
-pattern_key
-start_position
-end_position
right now i have this
dictionary[document] = {"pattern_key":key, "startPos":index_start, "endPos": index_end}
but i want to nest startPos, endPos under pattern key
Also how can i update this, to add a new entry of pattern_key, startPos, endPos, under same document?
with this you can updates values of the keys
for x in dict.keys():
if 'pattern_key' in x:
dict[x]= 'new value'
if 'endPost'...
.....
print dict
>>> should have new values
for add new entrys:
old = {}
old['keyxD'] = [9999]
new = {}
new['newnewnew'] = ['supernewvalue']
new.update(old)
print new
>>>{'newnewnew': ['supernewvalue'], 'keyxD': [9999]}
Not sure what you exactly want, but you can try this:
document = {'pattern_key' : {}}
This created an object document which is a dictionary, where the key is a string (pattern_key) and the value is another dictionary. Now, to add new entries to the value of the dictionary (which is another dictionary) you just add your values:
document['pattern_key']['start_position'] = 1
document['pattern_key']['end_position'] = 10
Afterwards, you can enter either case with document['pattern_key']['start_position'] = 2 and this will change the start position to 2.
Hope this helps

Categories