4

I was wondering is it possible to count for multiple strings using the .count function?

string = "abcdefg"
string.count("." or "!")

When I use the or command, it only gives me the count for 1 of the variables, but I want the total. How do you combine it such that it counts for 2 strings without splitting it into two functions?

Thanks

1
  • The or operator doesn't do what you want. See what print("." or "!") does. Also try print("." and "!"). You may find this answer of mine helpful in understanding what or and and do in Python. Commented Mar 18, 2017 at 9:09

7 Answers 7

4

Unfortunately, the built-in str.count function doesn't support doing counts of multiple characters in a single call. The other respondents both use multiple calls to str.count and make multiple passes over the data. I believe your question specified that you didn't want to split the calls.

If you aspire for a single-pass search in only one call, there are several other ways.

One way uses a regex such as len(re.findall(r'[ab]', s)) which counts the number of a or b characters in a single pass. You could even do this in a memory-efficient iterator form, sum(1 for _ in re.finditer(r'[ab]', s)).

Another way uses sets together with filter. For example, len(filter({'a', 'b'}.__contains__, s)) also counts the number of a or b characters in a single pass. You also do this one in a memory-efficient iterator form, sum(1 for _ in itertools.ifilter({'a', 'b'}.__contains__, s)).

>>> s = 'abracadabra'
>>> re.findall(r'[ab]', s)
['a', 'b', 'a', 'a', 'a', 'b', 'a']
>>> filter({'a', 'b'}.__contains__, s)
'abaaaba'

Just for grins, there is one other way but it is a bit off-beat, len(s) - len(s.translate(None, 'ab')). This starts with the total string length and subtracts the length of a translated string where the a and b characters have been removed.

Side note: In Python 3, filter() has changed to return an iterator. So the new code would become len(list(filter({'a', 'b'}.__contains__, s))) and sum(1 for _ in filter({'a', 'b'}.__contains__, s)).

Sign up to request clarification or add additional context in comments.

1 Comment

@PM2Ring Okay, I added a note.
1

You could use a counter: simple but may not be memory efficient.

string_ = "abcdefg"
from collections import Counter
counter = Counter(string_)
sum_ = counter['.'] + counter['!']

You could also simply use a list comprehension with sum (better):

string_ = "abcdefg"
sum_ = sum(1 for c in string_ if c in '.!' else 0)

1 Comment

This has the advantage of working in a single call as specified by the OP. The memory consumed is proportional the number of unique characters in the input, so even for large binary strings, it wouldn't exceed 256 entries in the Counter's dict. More likely the number will be smaller.
1

You can use this code, and set it to a variable and then print the variable.

text.count(".") + text.count("?") + text.count("!")

For example:

count = text.count(".") + text.count("?") + text.count("!")
print(count)

3

Comments

0

The or statement will select the . as is is not None and the method count will never see the exclamation mark. However, it would also not be able to handle two independent strings to count. So you need to do this separately.

string.count(".") + string.count("!")

1 Comment

I believe the OP didn't want str.count() to be called more than once. I think he is looking for a single-pass solution. That said, what you have is reasonable if only two or three characters are being counted; otherwise, it doesn't scale very well to larger input strings and more possible matching characters.
0

You can use sum method to get the total.

string = "abcdefg.a.!"

print(sum(string.count(i) for i in '.!'))

Output:

3

1 Comment

I believe the OP didn't want str.count() to be called more than once. I think he is looking for a single-pass solution. That said, what you have is reasonable if only two or three characters are being counted; otherwise, it doesn't scale very well to larger input strings and more possible matching characters.
0

You could use:

string.replace("!",".").count(".")

From preformance point of view I don't expect any benefit here, since the string hast to be parsed twice. However if your main motivation is to count the the chars in a one-liner (e.g. myFunctionReturnsString().replace("!",".").count(".")), this might help

Comments

0

Without using count(), you can split your original string and search string into arrays, and then check the length of their overlapping array

s = list('abcdefg.a.!')
t = list('.!')
print len([i for i in s if i in t])

>> 3

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.