Arithmetic sequences in Python

Antoon Pardon apardon at forel.vub.ac.be
Wed Jan 18 03:35:12 EST 2006

```Op 2006-01-18, Tom Anderson schreef <twic at urchin.earth.li>:
> On Tue, 17 Jan 2006, Antoon Pardon wrote:
>
>> Op 2006-01-16, Alex Martelli schreef <aleax at mail.comcast.net>:
>>> Paul Rubin <http://phr.cx@NOSPAM.invalid> wrote:
>>>
>>>> Steven D'Aprano <steve at REMOVETHIScyber.com.au> writes:
>>>>> solutions like range and xrange.
>>>>
>>>> Oh come on, [5,4,..0] is much easier to read than range(5,-1,-1).
>>>
>>> But not easier than reversed(range(6)) [[the 5 in one of the two
>>> expressions in your sentence has to be an offbyone;-)]]
>>
>> Why don't we give slices more functionality and use them.
>> These are a number of ideas I had. (These are python3k ideas)
>>
>> 1) Make slices iterables. (No more need for (x)range)
>>
>> 2) Use a bottom and stop variable as default for the start and
>>   stop attribute. top would be a value that is greater than
>>   any other value, bottom would be a value smaller than any
>>   other value.
>>
>> 3) Allow slice notation to be used anywhere a value can be
>>   used.
>>
>> 4) Provide a number of extra operators on slices.
>>   __neg__ (reverses the slice)
>>   __and__ gives the intersection of two slices
>>   __or__ gives the union of two slices
>>
>> 5) Provide sequences with a range (or slice) method.
>>   This would provide an iterator that iterates over
>>   the indexes of the sequences. A slice could be
>>   provided
>
> +5
>
>>  for i, el in enumerate(sequence):
>>
>> would become
>>
>>  for i in sequence.range():
>>    el = sequence[i]
>
> That one, i'm not so happy with - i quite like enumerate; it communicates
> intention very clearly. I believe enumerate is implemented with iterators,
> meaning it's potentially more efficient than your approach, too. And since
> enumerate works on iterators, which yours doesn't, you have to keep it
> anyway. Still, both would be possible, and it's a matter of taste.
>
>> But the advantage is that this would still work when someone subclasses
>> a list so that it start index is an other number but 0.
>
> It would be possible to patch enumerate to do the right thing in those
> situations - it could look for a range method on the enumerand, and if it
> found one, use it to generate the indices. Like this:
>
> def enumerate(thing):
>  	if (hasattr(thing, "range")):
>  		indices = thing.range()
>  	else:
>  		indices = itertools.count()
>  	return itertools.izip(indices, thing)

Fine by me. I'm not against enumerate.

>> If you only wanted every other index one could do the following
>>
>>  for i in sequence.range(::2):
>>
>> which would be equivallent to
>>
>>  for i in sequence.range() & (::2):
>
> Oh, that is nice. Still, you could also extend enumerate to take a range
> as an optional second parameter and do this with it. Six of one, half a
> dozen of the other, i suppose.

Yes you could probably do so and I'm not against it, I just think that
range would be a better base on which you can build enumerate and other
things than that enumenrate can be a base. e.g. __len__ could be eliminated
and len would be defined as:

def len(seq):
rng = seq.range()
return rng.stop - rng.start

```