slice notation as values?

Antoon Pardon apardon at forel.vub.ac.be
Sat Dec 10 06:54:43 EST 2005


On 2005-12-09, Duncan Booth <duncan.booth at invalid.invalid> wrote:
> Antoon Pardon wrote:
>
>>> If the user can write
>>>
>>>    for key in tree['a':'b']:
>>>
>>> then he can write:
>>>
>>>    for key in tree['a':'b'].iteritems():
>> 
>> No he can't. tree['a':'b'] would provide a list
>> of keys that all start with an 'a'. Such a list
>> doesn't have an iteritems method. It wouldn't even
>> contain the information to construct items.
>
> Why would it produce a list?

Correction, it produces an iterator.

> Slicing a *list* produces a list, slicing a tuple produces a tuple, slicing 
> a string produces a string. I would expect slicing any other type would 
> also return you a new object of the same type.

But iterating over a list, tuple or string, give you the elements
of a list, tuple or string one by one. Iterating over a dict
doesn't give you the elements one by one, but only the keys.

In general I use slices over a tree because I only want to iterate
over a specific subdomain of the keys. I'm not iterested in make
a tree over the subdomain. Making such a subtree would be an
enormous waste of resources. 

So even if we agree that tree['a':'b'] should create a subtree.
Then I still would want a way to iterate over a subdomain of
the keys in the tree without creating a subtree. Yes this
would create more than one way to do the same thing. But
this is already so with builtin dicts where a number of methods
give you different ways to do things, apparantly because
according to circumstances one is more efficient than the other.

So lets agree that tree['a':'b'] would produce a subtree. Then
I still would prefer the possibility to do something like:

  for key in tree.iterkeys('a':'b')

Instead of having to write

  for key in tree['a':'b'].iterkeys()

Sure I can now do it like this:

  for key in tree.iterkeys('a','b')

But the way default arguments work, prevents you from having
this work in an analague way as a slice.

With slice notation you could have the following two cases:

  for key in tree.iterkeys('a':)

  for key in tree.iterkeys(:'b')

But you can't do

  for key in tree.iterkeys('a',)

or more regrettably, you can't do:

  for key in tree.iterkeys(,'b')


I also think that other functions could benefit. For instance suppose
you want to iterate over every second element in a list. Sure you
can use an extended slice or use some kind of while. But why not extend
enumerate to include an optional slice parameter, so you could do it as
follows:

  for el in enumerate(lst,::2)

If you have an iterable, you sometime want to iterate over only a part
of it. The only way now to do so seems to be to either use a while
loop or create a second iterable over your limited domain and iterate
over the subiterable. I think it would be a an improvement if an
iterator could be constructed to just go over the subdomain within
your iterable. I also think that the most natural way to define
that subdomain would be by using slice notation.

-- 
Antoon Pardon



More information about the Python-list mailing list