I want a string such as 'ddxxx'
to be returned as ('d': 2, 'x': 3)
. So far I've attempted
result = {}
for i in s:
if i in s:
result[i] += 1
else:
result[i] = 1
return result
where s
is the string, however I keep getting a KeyError
. E.g. if I put s
as 'hello'
the error returned is:
result[i] += 1
KeyError: 'h'
The problem is with your second condition. if i in s
is checking for the character in the string itself and not in the dictionary. It should instead be if i in result.keys()
or as Neil mentioned It can just be if i in result
Example:
def fun(s):
result = {}
for i in s:
if i in result:
result[i] += 1
else:
result[i] = 1
return result
print (fun('hello'))
This would print
{'h': 1, 'e': 1, 'l': 2, 'o': 1}
You can solve this easily by using collections.Counter
. Counter is a subtype of the standard dict that is made to count things. It will automatically make sure that indexes are created when you try to increment something that hasn’t been in the dictionary before, so you don’t need to check it yourself.
You can also pass any iterable to the constructor to make it automatically count the occurrences of the items in that iterable. Since a string is an iterable of characters, you can just pass your string to it, to count all characters:
>>> import collections
>>> s = 'ddxxx'
>>> result = collections.Counter(s)
>>> result
Counter({'x': 3, 'd': 2})
>>> result['x']
3
>>> result['d']
2
Of course, doing it the manual way is fine too, and your code almost works fine for that. Since you get a KeyError
, you are trying to access a key in the dictionary that does not exist. This happens when you happen to come accross a new character that you haven’t counted before. You already tried to handle that with your if i in s
check but you are checking the containment in the wrong thing. s
is your string, and since you are iterating the character i
of the string, i in s
will always be true. What you want to check instead is whether i
already exists as a key in the dictionary result
. Because if it doesn’t you add it as a new key with a count of 1
:
if i in result:
result[i] += 1
else:
result[i] = 1
Using collections.Counter
is the sensible solution. But if you do want to reinvent the wheel, you can use the dict.get()
method, which allows you to supply a default value for missing keys:
s = 'hello'
result = {}
for c in s:
result[c] = result.get(c, 0) + 1
print result
output
{'h': 1, 'e': 1, 'l': 2, 'o': 1}
Here is a simple way of doing this if you don't want to use collections
module:
>>> st = 'ddxxx'
>>> {i:st.count(i) for i in set(st)}
{'x': 3, 'd': 2}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With