Reputation: 119
I'm trying to write a function count(s, chars)
that takes a string s
and a
list of characters chars
. The function should count the number of
occurrences of the letters given in chars
.
It should return a dictionary where the keys are
the characters given in the list of characters chars
.
So for example:
In [1]: s = "Another test string with x and y but no capital h."
In [2]: count(s, ['A', 'a', 'z'])
Out[2]: 'A': 1, 'a': 3, 'z': 0
I made some code that can count all the characters of the string and return a dictionary of it:
return {i: s.count(i) for i in set(s)}
but I'm not sure how you would use a list of specific characters and return a dictionary...
Upvotes: 7
Views: 14063
Reputation: 8178
str.count(sub[, start[, end]])
Return the number of non-overlapping occurrences of substring sub in the range [start, end]. Optional arguments start and end are interpreted as in slice notation.
e.g. usage
>>> sentence = 'Mary had a little lamb'
>>> sentence.count('a')
4
so count function can be easily used here in this scenario as well. Below is the sample code snippet of the function
li=['A', 'a', 'z']
s = "Another test string with x and y but no capital h."
def count(s, li):
cnt=dict.fromkeys(li, 0)
for c in li:
cnt[c] = s.count(c)
return cnt
Console output will be like
>>> count(s, li)
{'a': 3, 'A': 1, 'z': 0}
Upvotes: 3
Reputation: 13510
Well, so many answers, I will throw in mine too, which is based on built in constructs:
from collections import Counter
s = "Another test string with x and y but no capital h."
chars = ['A', 'a', 'z']
count = Counter(s) # creates a dictionary
count = {k:v for k, v in count.items() if k in chars} # take only charatcters from chars
count.update({k:0 for k in set(chars) - set(s)}) # add zero instances
print(count)
===
{'a': 3, 'A': 1, 'z': 0}
Upvotes: 1
Reputation: 103774
You can do it 'old style' by using the dict fromkeys
method to set all keys zeros and then increment for each character:
li=['A', 'a', 'z']
s = "Another test string with x and y but no capital h."
def count(s, li):
cnt={}.fromkeys(li, 0)
for c in s:
if c in cnt:
cnt[c]=cnt[c]+1
return cnt
>>> count(s, li)
{'A': 1, 'a': 3, 'z': 0}
Or, prefilter so you only test for keys that you are interested in:
def count(s, li):
cnt={}.fromkeys(li, 0)
for c in (e for e in s if e in cnt):
cnt[c]+=1
return cnt
But the fastest, most Pythonic is to use a Counter:
>>> from collections import Counter
>>> c=Counter(s)
>>> c
Counter({' ': 10, 't': 7, 'n': 4, 'h': 3, 'i': 3, 'a': 3, 'o': 2, 'e': 2, 'r': 2, 's': 2, 'A': 1, 'g': 1, 'w': 1, 'x': 1, 'd': 1, 'y': 1, 'b': 1, 'u': 1, 'c': 1, 'p': 1, 'l': 1, '.': 1})
Then construct your desired dict from that:
>>> {k:c[k] for k in li}
{'A': 1, 'a': 3, 'z': 0}
Upvotes: 2
Reputation: 10951
You can also build a dictionary with zip
built-in method:
>>> s
'Another test string with x and y but no capital h.'
>>> c
['A', 'a', 'z']
>>> def count_char(s, c):
counts = map(s.count, c)
return dict(zip(c, counts))
>>>
>>> count_char(s, c)
{'z': 0, 'A': 1, 'a': 3}
Upvotes: 1
Reputation: 41
def count(s, chars):
ret = dict(zip(chars, [0 for c in chars]))
for c in s:
if ret.has_key(c):
ret[c] += 1
return ret
Something like that maybe.
Upvotes: 1
Reputation: 476574
What about:
def count_chars(s,chars):
return {c : s.count(c) for c in chars}
Generates:
$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> s = "Another test string with x and y but no capital h."
>>> def count_chars(s,chars):
... return {c : s.count(c) for c in chars}
...
>>> count_chars(s, ['A', 'a', 'z'])
{'z': 0, 'A': 1, 'a': 3}
Although this is rather inefficient. Probably a more efficiency way is do the counting in one step. You can use a Counter
for this and then retain the interesting characters:
from collections import Counter
def count_chars(s,chars):
counter = Counter(s)
return {c : counter.get(c,0) for c in chars}
Upvotes: 6