Python Forum
How to exclude characters when counting digits
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to exclude characters when counting digits
#11
(Jul-03-2018, 11:27 AM)gruntfutuk Wrote: I didn't run time it.
import timeit
import string

my_string = 'DS80A98SD09a8SD098ASD098A09sd8c0a9SCNAfsdg8fbvdfad098098f00A'*1000

def count_func(s):
    return sum(c.isdigit() for c in s)


def smart_count_digits(my_string):
    orig_length = len(my_string)
    for digit in string.digits:
        my_string = my_string.replace(digit, '')
    return orig_length - len(my_string)

elapsed = timeit.timeit('count_func(my_string)', number=1000, setup='from __main__ import count_func, my_string')
print( 'count_func took {:.3f} sec'.format(elapsed))

elapsed = timeit.timeit('smart_count_digits(my_string)', number=1000, setup='from __main__ import smart_count_digits, my_string')
print('smart_count_digits took {:.3f} sec'.format(elapsed))
Output:
count_func took 15.112 sec smart_count_digits took 1.181 sec
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#12
(Jul-03-2018, 11:59 AM)buran Wrote:
Output:
count_func took 15.112 sec smart_count_digits took 1.181 sec

Brilliant. Thanks for the timings. I expect my original was probably also faster. I'm going to have to start timing things more often.
I am trying to help you, really, even if it doesn't always seem that way
Reply
#13
def ick_count(text):
    return len(text) - sum([text.count(digit) for digit in string.digits])
Output:
count_func took 6.773 sec smart_count_digits took 0.908 sec ick_count took 0.550 sec
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#14
(Jul-03-2018, 11:27 AM)gruntfutuk Wrote:
def count_func(s):
    return sum(c.isdigit() for c in s)
would be pretty efficient, but I didn't run time it.

I like this solution also, but I can't test it.
My CPU Speed is not fixed, so I get not usable results.

I guess the methodcall isdigit() takes bit time.
Maybe this can be faster:

import string


def count_func(s):
    return sum(1 for c in s if c in set(string.digits))
But again, I can't benchmark it :-/
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#15
digit_re = re.compile('\d+')

def re_count(text):
    return len(text) - len(digit_re.sub(text, ''))
Output:
count_func took 7.043 sec smart_count_digits took 0.945 sec ick_count took 0.622 sec re_count took 0.061 sec
Edit: Function gave wrong answer, corrected function and reran times.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#16
On further examination, both my functions are giving the wrong answer, so they shouldn't be considered.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#17
(Jul-03-2018, 01:29 PM)ichabod801 Wrote: On further examination, both my functions are giving the wrong answer, so they shouldn't be considered.

I'm on comute, so would you timeit this one
def ick_count(text):
    return sum(text.count(digit) for digit in string.digits)
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#18
On my iPad:
print('smart:',timeit.timeit("smart_count_digits(my_string)", setup = "from __main__ import smart_count_digits, my_string", number = 1000))
print('count:',timeit.timeit("count_digits(my_string)", setup = "from __main__ import count_digits, my_string", number = 1000))
print('ick:',timeit.timeit("ick_count(my_string)", setup = "from __main__ import ick_count, my_string", number = 1000))
Output:
smart: 1.1727769580029417 count: 8.195804083981784 ick: 0.5881457919895183
ick_count is the winner.
I am trying to help you, really, even if it doesn't always seem that way
Reply
#19
After a lecture recently delivered in another forum about the evilness of the non-functional ways Hand , I started playing around with map, filter and reduce (I was using them occasionally before, but I decided to raise my level of involvement)

So, adding map to @ichabod801's solution should have brought salvation Pray ? Apparently not Confused

Output:
In [4]: def ick_count(text): ...: return sum(text.count(digit) for digit in string.digits) ...: ...: def ick_map_count(text): ...: return sum(map(text.count, string.digits)) ...: ...: In [5]: %timeit ick_count(my_string) 423 µs ± 6.69 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) In [6]: %timeit ick_map_count(my_string) 423 µs ± 10.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Test everything in a Python shell (iPython, Azure Notebook, etc.)
  • Someone gave you an advice you liked? Test it - maybe the advice was actually bad.
  • Someone gave you an advice you think is bad? Test it before arguing - maybe it was good.
  • You posted a claim that something you did not test works? Be prepared to eat your hat.
Reply
#20
(Jul-03-2018, 01:13 PM)DeaD_EyE Wrote:
import string
def count_func(s):
    return sum(1 for c in s if c in set(string.digits))

It may be re-written as
def count_func(s):
    return sum(c in set(string.digits) for c in s)
You can add booleans as integers.

Still, major loser to @ichabod801
Output:
In [8]: %timeit dead_eye_count_func(my_string) 31.8 ms ± 1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) In [9]: %timeit ick_count(my_string) 467 µs ± 12 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
With a little tweak - making set of digits "static"
Output:
In [12]: def frozen_set_count_func(s, _digits=frozenset(string.digits)): ...: return sum(c in _digits for c in s) ...: In [13]: %timeit frozen_set_count_func(my_string) 5.7 ms ± 264 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Test everything in a Python shell (iPython, Azure Notebook, etc.)
  • Someone gave you an advice you liked? Test it - maybe the advice was actually bad.
  • Someone gave you an advice you think is bad? Test it before arguing - maybe it was good.
  • You posted a claim that something you did not test works? Be prepared to eat your hat.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Counting the number of occurrences of characters in a string nsadams87xx 1 1,877 Jun-16-2020, 07:22 PM
Last Post: bowlofred

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020