msg80368 - (view) |
Author: Steve (steve21) |
Date: 2009-01-22 13:14 |
I'd like to request a 'step' argument be added for itertools.count. It
would be useful in the same way that step is useful for the 'range'
function.
('range' and 'count' are very similar - 'count' could even be merged into
'range', for example by making 'range(None)' equivalent to 'count()')
|
msg80384 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2009-01-22 21:56 |
Am not too excited about this one. As a heavy itertools user myself,
I've never had occasion to need a step argument. As an implementer, I'm
aware that it would make the code for count() much more complex (because
of the internal optimizations and because step can be positive,
negative, or zero).
Have you had any real world use cases where count(start, step) would
have been the best solution?
|
msg80605 - (view) |
Author: Steve (steve21) |
Date: 2009-01-27 01:42 |
Here's a couple of functions I use with count and step:
def cf_e():
'''return: (iterator) the infinite continued fraction for e
e=[2; 1, 2, 1, 1, 4, 1, 1, 6, 1 , ... , 1, 2k, 1, ...]
'''
yield 2
for k in itertools.count(2, 2):
yield 1
yield k
yield 1
def prime_factors(n):
'''n: (int > 1)
return: (list) the sorted list of tuples (p,e) of prime factors of n
p is a prime factor, e is the number of times the factor is used
'''
ret = []
if n <= 1:
return ret
# factors: use known (small) primes, then possible primes (odd numbers)
for factor in itertools.chain([2,3,5,7,11], itertools.count(13, 2)):
if factor*factor > n:
if n != 1:
ret += [(n, 1)]
break
for e in itertools.count(0):
div, mod = divmod(n, factor)
if mod != 0:
break
n = div
if e >= 1:
ret += [(factor, e)]
return ret
|
msg80609 - (view) |
Author: David W. Lambert (LambertDW) |
Date: 2009-01-27 02:48 |
Nice. Now I know that $e$ is a least transcendental number. But I
can't figure out why inserting this code into your file (and removing
some "itertools.") is difficult or unreadable. I maintain a personal
library of modules that I don't actually expect Guido to include in the
python standard library.
import itertools
def count(offset=0,stride=1):
for i in itertools.count():
yield offset+i*stride
# this version probably performs faster
def count(offset=0,stride=1):
while True:
yield offset
offset += stride
|
msg80614 - (view) |
Author: Steve (steve21) |
Date: 2009-01-27 03:56 |
I already use the second version of the count function you give (without
default arguments which I am not a big fan of). I'm not saying its
difficult or unreadable to bypass itertools.count and write your own
enhanced count function. But if I use a custom count function, you use a
custom count function, and possibly many others too, then there could be
a common requirement for a step argument and it might be a good idea too
make it more widely available.
Haskell has a powerful and concise list notation, some of which Python
has already borrowed from:
multiple3 = [3,6..]
|
msg80618 - (view) |
Author: David W. Lambert (LambertDW) |
Date: 2009-01-27 04:37 |
Probably a better prime factor algorithm uses Sieve of E. to generate
primes through int(1+sqrt(n)) and test these.
The other algorithm uses a custom generator anyway. Oh well, good luck,
I'll shut up.
You do have use cases that I couldn't think of.
Dave.
|
msg80643 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2009-01-27 10:55 |
I've looked again at what it would take to update the C code and think
that the optimizations there make it difficult to add this feature
without adding a lot of code complexity and without slowing-down the
common case. Also, I value the simplicity of the current API.
Suggest you use "range(start, sys.maxsize, step)" or just roll your own
generator (like Lambert's second version).
|
msg81725 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2009-02-12 05:40 |
Found a way to do this while keeping full speed on the default case.
Also, fixed an error where the start argument was rounded to the nearest
integer.
Also, improved the utility over its cousin, range() by allowing floating
point arguments.
See r69522
|
msg81736 - (view) |
Author: Mark Dickinson (mark.dickinson) * |
Date: 2009-02-12 10:57 |
A couple of comments:
> Also, improved the utility over its cousin, range() by allowing floating
> point arguments.
Is this wise? From a numerical perspective, it seems to me that using
count with floating-point arguments is almost always going to be the
wrong thing to do (unless those floats are integral), and that allowing
floating-point arguments invites misuse. For example, I'd be suspicious
of code that looked like:
for x in count(0.0, 0.1):
do_something_with_x
where it seems quite likely that what's intended is the more robust:
for i in count():
x = i/10.0
do_something_with_x
Second (unrelated) comment: on my machine, list(count()) appears to
hang, and is unresponsive to keyboard interrupts. Is there any easy way
to make this interruptible? While list(count()) is clearly a stupid
thing to type, it would be nice if it didn't hang the interpreter.
|
msg81745 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2009-02-12 11:56 |
Not too worried about either issue. For the first, it makes the code
closer to its pure python equivalent. Better to add some math module
function like Matlab's linspace(). It's hard to prevent people from
creating numerical mistakes no matter what. Besides, now it's possible
to write: count(Decimal('1.1'), Decimal('.1')) and get exact
progressions.
For the second, the non-interruptability issue is everpresent throughout
the language. If we get some uniform way of dealing with it, that would
be great (though I expect it will slow down lots of things we care about
and provide nearly zero benefit). Since count() and repeat() came out
in itertools eons ago, there have been zero bug reports or user
complaints about the issue. So, I'll take it as a non-issue.
|
msg81748 - (view) |
Author: Mark Dickinson (mark.dickinson) * |
Date: 2009-02-12 12:02 |
> to write: count(Decimal('1.1'), Decimal('.1')) and get exact
> progressions.
That's pretty cool. :-)
> in itertools eons ago, there have been zero bug reports or user
> complaints about the issue. So, I'll take it as a non-issue.
Fair enough.
|
msg81758 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2009-02-12 12:40 |
More coolness:
count(Fraction(2,3), Fraction(1,6))
|
msg81800 - (view) |
Author: David W. Lambert (LambertDW) |
Date: 2009-02-12 18:47 |
I run my shells with low priority so I can sneak around and kill them.
|
|
Date |
User |
Action |
Args |
2022-04-11 14:56:44 | admin | set | github: 49282 |
2009-02-12 18:47:56 | LambertDW | set | messages:
+ msg81800 |
2009-02-12 12:40:33 | rhettinger | set | messages:
+ msg81758 |
2009-02-12 12:02:18 | mark.dickinson | set | messages:
+ msg81748 |
2009-02-12 11:56:49 | rhettinger | set | messages:
+ msg81745 |
2009-02-12 10:57:48 | mark.dickinson | set | nosy:
+ mark.dickinson messages:
+ msg81736 |
2009-02-12 05:42:46 | rhettinger | set | status: open -> closed resolution: accepted |
2009-02-12 05:40:41 | rhettinger | set | messages:
+ msg81725 |
2009-01-27 10:55:49 | rhettinger | set | messages:
+ msg80643 |
2009-01-27 04:37:53 | LambertDW | set | messages:
+ msg80618 |
2009-01-27 03:56:59 | steve21 | set | messages:
+ msg80614 |
2009-01-27 02:48:02 | LambertDW | set | messages:
+ msg80609 |
2009-01-27 01:42:17 | steve21 | set | messages:
+ msg80605 |
2009-01-23 04:36:58 | LambertDW | set | nosy:
+ LambertDW |
2009-01-22 21:56:03 | rhettinger | set | messages:
+ msg80384 |
2009-01-22 18:43:00 | rhettinger | set | priority: low assignee: rhettinger nosy:
+ rhettinger components:
+ Extension Modules, - None versions:
+ Python 3.1, Python 2.7, - Python 3.0 |
2009-01-22 13:14:30 | steve21 | create | |