Here's a way using collections.Counter
:
Suppose the string you provided was stored in a variable s
.
First we iterate over the set of all lower case letters in s
. We do this by making another string s_lower
which will convert the string s
to lowercase. We then wrap this with the set
constructor to get unique values.
For each char
, we iterate through the string and check to see if the previous letter is equal to char
. If so, we store this in a list. Finally, we pass this list into the collections.Counter
constructor which will count the occurrences.
Each counter is stored in a dictionary, counts
, where the keys are the unique characters in the string.
from collections import Counter
counts = {}
s_lower = s.lower()
for char in set(s_lower):
counts[char] = Counter(
[c for i, c in enumerate(s_lower) if i > 0 and s_lower[i-1] == char]
)
For your string, this has the following outputs:
>>> print(counts['s'])
#Counter({'i': 1, 'e': 1, 'o': 1})
>>> print(counts['o'])
#Counter({' ': 2, 'd': 1, 'n': 1, 'u': 1})
One caveat is that this method will iterate through the whole string for each unique character, which could potentially make it slow for large lists.
Here is an alternative approach using collections.Counter
and collections.defaultdict
that only loops through the string once:
from collections import defaultdict, Counter
def count_letters(s):
s_lower = s.lower()
counts = defaultdict(Counter)
for i in range(len(s_lower) - 1):
curr_char = s_lower[i]
next_char = s_lower[i+1]
counts[curr_char].update(next_char)
return counts
counts = count_letters(s)
We loop over each character in the string (except the last) and on each iteration we update a counter using the next character.