How to create a dictionary from a string returning the number of characters

I want a string such as 'ddxxx'

to return like ('d': 2, 'x': 3)

. So far I've tried

result = {}
for i in s:
    if i in s:
        result[i] += 1
    else:
        result[i] = 1
return result   

      

where s

is a string, however I keep getting KeyError

. For example. if i put s

like 'hello'

then the returned error is:

result[i] += 1
KeyError: 'h'

      

+3


source to share


4 answers


The problem is with your second condition. if i in s

checks for a character in the string itself, not in the dictionary. It should be if i in result.keys()

or as mentioned Neil It could be simpleif 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 will print

{'h': 1, 'e': 1, 'l': 2, 'o': 1}

      

+3


source


This can be easily solved using collections.Counter

. A counter is a subtype of the standard dictation that is done to count things. It will automatically make sure that indexes are created when you try to increment something that was not previously in the dictionary, so you don't have to check it yourself.

You can also pass any iterable value to the constructor so that it automatically counts occurrences of elements in that iterable. Since a string is character iterable, you can simply 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 manually is fine too, and your code is almost perfect for that. Since you are getting KeyError

, you are trying to access a key in the dictionary that doesn't exist. This happens when you come to a new character that you did not consider before. You have already tried to deal with this with validation if i in s

, but you are testing containment for the wrong reason. s

is your string, and since you are repeating a i

string character i in s

will always be true. Instead, you want to check if i

as a key exists in the dictionary result

. Because if it doesn't add it as a new account key 1

:

if i in result:
    result[i] += 1
else:
    result[i] = 1

      

+7


source


Usage collections.Counter

is a smart decision. But if you want to reinvent the wheel, you can use a method dict.get()

that allows you to specify a default 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}

      

+2


source


Here's an easy way to do it if you don't want to use a module collections

:

>>> st = 'ddxxx'
>>> {i:st.count(i) for i in set(st)}
{'x': 3, 'd': 2}

      

+1


source







All Articles