Reputation: 45
How can I initialise a python dictionary with keys that are not pre-determined?
If I just initialise the dictionary with dict = {}
, it gives me a Key Error once I try to populate it with new key-value pairs.
A workaround would be to do a try-except so that it tries to access existing keys first or initialises the dictionary for a new key if the former fails. A concrete example would be counting words in a text (this code example would lead to a Key Error
):
wordcount = {}
for word in text:
wordcount[word] += 1
Upvotes: 2
Views: 4315
Reputation: 1001
word_count = {}
for word in text:
word_count[word] = word_count.setdefault(word, 0) + 1
Upvotes: 0
Reputation: 10951
If I've understood your objective here which is to get a dict
of word:count mapping, then you could do it also with dictionary comprehension(taking example of idjaw
):
>>> text = ["this", "is", "my", "sentence", "yes", "it", "is", "my", "stuff"]
>>>
>>> {c:text.count(c) for c in text}
{'it': 1, 'my': 2, 'yes': 1, 'is': 2, 'stuff': 1, 'this': 1, 'sentence': 1}
Or also Counter
from collections
module would also do the job:
>>> from collections import Counter
>>>
>>> c = Counter()
>>>
>>> for word in text:
c[word] += 1
>>> c
Counter({'my': 2, 'is': 2, 'it': 1, 'yes': 1, 'stuff': 1, 'this': 1, 'sentence': 1})
>>>
Upvotes: 0
Reputation: 26580
With the approach that you are doing, the way you should be doing this is checking to see if the key exists already by using the in
keyword. If it does then do your increment, otherwise just assign 1. like this:
wordcount = {}
text = ["this", "is", "my", "sentence", "yes", "it", "is", "my", "stuff"]
for word in text:
if word in wordcount:
wordcount[word] += 1
else:
wordcount[word] = 1
print(wordcount)
# {'yes': 1, 'stuff': 1, 'sentence': 1, 'my': 2, 'is': 2, 'this': 1, 'it': 1}
Per your comments, you can avoid this condition if you actually use defaultdict
from the collections
module (documentation). You simply set what the default
value is to your dictionary entries and proceed with your +=
. Example:
from collections import defaultdict
my_dict = defaultdict(int)
text_list = ["this", "is", "my", "sentence", "yes", "it", "is", "my", "stuff"]
for text in text_list:
my_dict[text] += 1
print(my_dict)
# defaultdict(<class 'int'>, {'sentence': 1, 'this': 1, 'is': 2, 'my': 2, 'yes': 1, 'it': 1, 'stuff': 1})
Now, if you are simply trying to count words in text, then there is something built-in to do this already for you called Counter
from the collections
module (documentation). This will keep a count of all like elements. Observe the example:
from collections import Counter
text = ["this", "is", "my", "sentence", "yes", "it", "is", "my", "stuff"]
my_count_dict = Counter(text)
print(my_count_dict)
Counter({'my': 2, 'is': 2, 'stuff': 1, 'this': 1, 'it': 1, 'sentence': 1, 'yes': 1})
Pay attention to the output as it is in order of most frequent. If you need to get the most common word, call most_common
on it:
print(my_count_dict.most_common(1))
# [('my', 2)]
Upvotes: 2
Reputation: 8437
No need to initialize your dict with predefined values.
You also don't need any try/except, but just use Python's defaultdict
with the default type set to int
:
from collections import defaultdict
wordcount = defaultdict(int)
for word in text:
wordcount[word] += 1
However, if you just need to count the words in a list, Python also had a helper class called Counter
, in collections as well.
Upvotes: 3
Reputation: 4687
You need firstly to add key-value pair to your dict.
wordcount = {}
for word in text:
if word not in wordcount:
wordcount[word] = 0
wordcount[word] += 1
Upvotes: 0
Reputation: 1298
You need to make sure to initialize the keys before you try to increment them (+=1
). Try this:
wordcount = {}
text = ["word","foo","word","word","bar","bar","word","something"]
for word in text:
if word in wordcount: # tests to see if the key exists already
wordcount[word] += 1
else: # initializes the key to 1
wordcount[word] = 1
print(wordcount)
# prints {'bar': 2, 'word': 4, 'something': 1, 'foo': 1}
Upvotes: 0