Perl's @foo[3,7,1,-1] ?

Steven D'Aprano steve at REMOVETHIS.cybersource.com.au
Sun Jun 14 15:01:30 CEST 2009


kj wrote:

> OK, I see: if Python allowed foo[3,7,1,-1], then foo[3] would be
> ambiguous: does it mean the fourth element of foo, or the tuple
> consisting of this element alone?  I suppose that's good enough
> reason to veto this idea...

There's nothing ambiguous about it. obj.__getitem__(x) already accepts two
different sorts of objects for x: ints and slice-objects:

>>> range(8)[3]
3
>>> range(8)[slice(3)]
[0, 1, 2]
>>> range(8)[slice(3, None)]
[3, 4, 5, 6, 7]
>>> range(8)[slice(3, 4)]
[3]


Allowing tuple arguments need not be ambiguous:

range(8)[3] => 3
range(8)[(3,)] => [3]
range(8)[(3,5,6)] => [3, 5, 6]


I've rarely needed to grab arbitrary items from a list in this fashion. I
think a more common case would be extracting fields from a tuple. In any
case, there are a few alternatives:


Grab them all, and ignore some of them (ugly for more than one or two
ignorable items):

_, x, _, _, y, _, _, _, z, _ = range(10)  # x=1, y=4, z=9


Subclass list to allow tuple slices:

>>> class MyList(list):
...     def __getitem__(self, obj):
...             if type(obj) is tuple:
...                     return [self[i] for i in obj]
...             else:
...                     return list.__getitem__(self, obj)
...
>>> L = MyList(range(10))
>>> L[(1, 4, 8)]
[1, 4, 8]


Write a helper function:

def getitems(L, *indexes):
    if len(indexes) == 1:
        indexes = indexes[0]
    return [L[i] for i in indexes]


But I think this is an obvious enough extension to the __getitem__ protocol
that I for one would vote +1 on it being added to Python sequence objects
(lists, tuples, strings).


-- 
Steven




More information about the Python-list mailing list