Posts: 8,165
Threads: 160
Joined: Sep 2016
(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
Posts: 232
Threads: 2
Joined: Sep 2017
(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
Posts: 4,220
Threads: 97
Joined: Sep 2016
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
Posts: 2,128
Threads: 11
Joined: May 2017
(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 :-/
Posts: 4,220
Threads: 97
Joined: Sep 2016
Jul-03-2018, 01:23 PM
(This post was last modified: Jul-03-2018, 01:23 PM by ichabod801.)
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.
Posts: 4,220
Threads: 97
Joined: Sep 2016
On further examination, both my functions are giving the wrong answer, so they shouldn't be considered.
Posts: 8,165
Threads: 160
Joined: Sep 2016
Jul-03-2018, 01:36 PM
(This post was last modified: Jul-03-2018, 01:36 PM by buran.)
(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)
Posts: 232
Threads: 2
Joined: Sep 2017
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
Posts: 566
Threads: 10
Joined: Apr 2017
Jul-03-2018, 05:01 PM
(This post was last modified: Jul-03-2018, 05:02 PM by volcano63.)
After a lecture recently delivered in another forum about the evilness of the non-functional ways  , 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  ? Apparently not
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.
Posts: 566
Threads: 10
Joined: Apr 2017
(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.
|