List indexing multiple elements

Apologies if this has already been covered! Right now, if you want to get multiple elements in a list, you have to do: elements = [mylist[a], mylist[b]] My proposal is two-folded: - Right now, a[b,c] is already valid syntax, since it's just indexing a with the tuple (b, c). The proposal is to make this a specialization in the grammar, and also allow stuff like a[b:c, d:e] (like `a.__getitem__(slice(b, c), slice(d, e))`). - Add support for indexing via tuples in list.__getitem__. list.__getitem__(tuple) would roughly be equivalent to map(list.__getitem__, tuple). The first part is solely so that slices would be allowed in the syntax, but if you guys don't like the idea, the second part still stands. Thoughts? *ducks from flying tomatoes* -- Ryan (ライアン) Yoko Shimomura > ryo (supercell/EGOIST) > Hiroyuki Sawano >> everyone else http://refi64.com

So, to make sure I have this right: your proposal says array should be indexable by a list of indexes as they're currently done, in a tuple, right? Would this also mean that something like (1:4, 8:10, 13) should be an acceptable constructor for a tuple? -Ryan Birmingham On 20 February 2017 at 15:54, Ryan Gonzalez <rymg19@gmail.com> wrote:

On Mon, Feb 20, 2017 at 3:55 PM Ryan Gonzalez <rymg19@gmail.com> wrote:
The syntax/grammar already permits slices to be used in this fashion: Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information.

On 20 February 2017 at 20:54, Ryan Gonzalez <rymg19@gmail.com> wrote:
I'm not sure what you mean by a "specialisation in the grammar". This is currently valid syntax. It's only list.__getitem__ that rejects it:
That error comes from lst.__getitem__, not from the grammar.
But they already are...
Thoughts? *ducks from flying tomatoes*
Thoughts on the second path, then. I presume you're aware this can be done right now using a helper function. And indeed you point out yourself that it's basically map(lst.__getitem__, seq). So I guess the key question is what *additional* benefit do you see to this proposal that justifies adding it to the builtin list type *now*, when people have managed fine this far without it. Paul

On Mon, Feb 20, 2017 at 12:54 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
This part is DOA. As someone else notes, use of tuples as indexers is commonplace in NumPy (and Pandas, XArray, Dask, etc). In those collection types, the comma refers to dimensions of the data. However, as someone else notes, you can create whatever meaning you want for indexing with a tuple. I think it would be confusing to give a meaning very different from that in NumPy; but it's perfectly syntactical. class MultisliceList(list): def __getitem__(self, arg): if isinstance(arg, int) or isinstance(arg, slice): return list.__getitem__(self, arg) elif isinstance(arg, tuple): indices = set() for x in arg: if isinstance(x, int): indices.add(x) elif isinstance(x, slice): for i in range(x.start or 0, x.stop, x.step or 1): indices.add(i) else: raise NotImplementedError("Can only index with ints and slices") else: raise NotImplementedError("Can only index with ints and slices") return MultisliceList([list.__getitem__(self, i) for i in sorted(indices)]))
l = MultisliceList(range(1000,0,-5)) l[10:15], type(l[10:15])
([950, 945, 940, 935, 930], list)
l[9], type(l[9])
(955, int)
msl = l[9,110:115,10:15,100] msl, type(msl)
([955, 950, 945, 940, 935, 930, 500, 450, 445, 440, 435, 430], __main__.MultisliceList) I decided that the various index positions indicated should be in sorted order (there might be overlap in tuple items). Also I didn't make a single slice stay as the special class. You can write your version however you like. -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

So, to make sure I have this right: your proposal says array should be indexable by a list of indexes as they're currently done, in a tuple, right? Would this also mean that something like (1:4, 8:10, 13) should be an acceptable constructor for a tuple? -Ryan Birmingham On 20 February 2017 at 15:54, Ryan Gonzalez <rymg19@gmail.com> wrote:

On Mon, Feb 20, 2017 at 3:55 PM Ryan Gonzalez <rymg19@gmail.com> wrote:
The syntax/grammar already permits slices to be used in this fashion: Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information.

On 20 February 2017 at 20:54, Ryan Gonzalez <rymg19@gmail.com> wrote:
I'm not sure what you mean by a "specialisation in the grammar". This is currently valid syntax. It's only list.__getitem__ that rejects it:
That error comes from lst.__getitem__, not from the grammar.
But they already are...
Thoughts? *ducks from flying tomatoes*
Thoughts on the second path, then. I presume you're aware this can be done right now using a helper function. And indeed you point out yourself that it's basically map(lst.__getitem__, seq). So I guess the key question is what *additional* benefit do you see to this proposal that justifies adding it to the builtin list type *now*, when people have managed fine this far without it. Paul

On Mon, Feb 20, 2017 at 12:54 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
This part is DOA. As someone else notes, use of tuples as indexers is commonplace in NumPy (and Pandas, XArray, Dask, etc). In those collection types, the comma refers to dimensions of the data. However, as someone else notes, you can create whatever meaning you want for indexing with a tuple. I think it would be confusing to give a meaning very different from that in NumPy; but it's perfectly syntactical. class MultisliceList(list): def __getitem__(self, arg): if isinstance(arg, int) or isinstance(arg, slice): return list.__getitem__(self, arg) elif isinstance(arg, tuple): indices = set() for x in arg: if isinstance(x, int): indices.add(x) elif isinstance(x, slice): for i in range(x.start or 0, x.stop, x.step or 1): indices.add(i) else: raise NotImplementedError("Can only index with ints and slices") else: raise NotImplementedError("Can only index with ints and slices") return MultisliceList([list.__getitem__(self, i) for i in sorted(indices)]))
l = MultisliceList(range(1000,0,-5)) l[10:15], type(l[10:15])
([950, 945, 940, 935, 930], list)
l[9], type(l[9])
(955, int)
msl = l[9,110:115,10:15,100] msl, type(msl)
([955, 950, 945, 940, 935, 930, 500, 450, 445, 440, 435, 430], __main__.MultisliceList) I decided that the various index positions indicated should be in sorted order (there might be overlap in tuple items). Also I didn't make a single slice stay as the special class. You can write your version however you like. -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
participants (6)
-
David Mertz
-
Ivan Levkivskyi
-
Jonathan Goble
-
Paul Moore
-
Ryan Birmingham
-
Ryan Gonzalez