I see that there is a thread of a similar topic that was posted recently (
enumerate with a start index ) but thought I would start a new thread since
what I am suggesting is a little different.
Whenever I use enumerate, I am doing so because I will use the index to access
some other element in the list (the previous or next, usually) while also
looking at the element that is returned from enumerate. Several times,
however, in the development phase of the work, I end up sending a subset of the
list at hand and then get bitten by the fact that the indices returned by
enumerate are not the indices of the original list, they are the indices of the
slice that I sent. e.g. in the following, "0" is the first index but I wanted
it to be 3
###
>>> start=3
>>> count=5
>>> for i, x in enumerate(range(10)[start:start+count]):
... print i, x
...
0 3
1 4
2 5
3 6
4 7
>>>
###
What I would propose is an optional slice argument to the enumerate routine
that would allow enumerate to return elements that are synchronized with the
original list list/iterable elements. e.g.
def enum(l, slc=None):
if slc==None:
for i, dat in enumerate(l):
yield i, dat
else:
if type(slc)<>slice:
raise TypeError, "slc must be a valid slice"
start, step = slc.start, slc.step
# we need actual values for start and step, so check for None
# and supply defaults
if step==None:step=1
if start==None:
if step>0:
start=0
else:
start=-1
for i, dat in enumerate(l[slc]):
j = i*step+start
if j<0: j+=len(l)
yield j, dat
###
>>> for i, x in enum(range(10), slice(start, start+count)):
... print i, x
...
3 3
4 4
5 5
6 6
7 7
>>> for i, j in enum(range(10), slice(None,None,-3)):
... print i,j
...
9 9
6 6
3 3
0 0
>>>
###
An advantage to processing the iteratable with a slice argument is that then
the slice information is given only once and it can do 2 things: slice the
original iterable and provide the synchronized indices.
NOTE: the same thing that I am proposing could also be done with count and izip
if count had a step argument, but it's more ackward and you have to supply the
same information in two places:
>>> def count(start, step=1):
... for i in itertools.count(start):
... yield start+(i-start)*step
...
>>>
>>> start=3; stop=None; step=2
>>> for i,j in itertools.izip(count(start, step), itertools.islice(range(10),
>>> start, stop, step)):
... print i,j
...
3 3
5 5
7 7
9 9
A "P.S." question for this email is, was there a reason to leave step out of
itertools.count?
/c
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com