[Python-bugs-list] [ python-Feature Requests-419903 ] Non-contiguous indexing and slicing

SourceForge.net noreply@sourceforge.net
Mon, 12 May 2003 16:48:47 -0700


Feature Requests item #419903, was opened at 2001-04-28 19:38
Message generated for change (Comment added) made by bcannon
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=355470&aid=419903&group_id=5470

>Category: Python Interpreter Core
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Tim Cera (timcera)
Assigned to: Nobody/Anonymous (nobody)
Summary: Non-contiguous indexing and slicing

Initial Comment:
I don't know if this has been talked about, I 
couldn't find it in the PEPs, newsgroup or web site.

I use PV-WAVE, a matrix manipulation language similar to 
MatLab and IDL.  PV-WAVE and IDL have the same ancestry. 
Python, along with arrays from Numeric Python makes a 
pretty good substitute for PV-WAVE.  Plus there are many 
simularities in syntax between Python and PV-WAVE.

PV-WAVE code:

PV-WAVE> a=[10,20,30,40,50,60,70,80,90]
PV-WAVE> b=[0,4,5,7]
PV-WAVE> c=a(b)
PV-WAVE> print,c
[10, 50, 60, 80]

Non-contiguous indexing or is it non-contiguous slicing?  
Actually it should probably be called dicing.  :-)

Anyway, I would really like that for Python, so here 
goes...

I find myself doing the following to replicate PV-WAVE's 
behavoir:

>>> a=[10,20,30,40,50,60,70,80,90]
>>> b=[0,4,5,7]
>>> c=[] 
>>> for i in b:
...   c.append(a[i])
...
>>> c
[10, 50, 60, 80]

First, just taking the idea from PV-WAVE, for example:

>>> c=a[0,4,5,7]
>>> c
[10,50,60,80]

Extending it to include ranges:

>>> a[0:3,6:-1]
[10,20,30,70,80]

Maybe overlapping ranges and mix of indexing and 
slicing:

>>> a[0:4,3:4,0:-1,-1]
[10,20,30,40,40,10,20,30,40,50,60,70,80,90]

There are some issues:  
 The comma is used in Numerical Python to seperate the 
array coordinates, so a[0:3,6:-1] is already a 
legitimate Numerical Python statement. 
 It isn't very pretty.

Maybe have a 'dice()' function?

>>> a=[10,20,30,40,50,60,70,80,90]
>>> b=[0,4,5,7]
>>> c=a.dice(b)    # or c=dice(a,b)  ?
>>> c
[10,50,60,80]

Thanks for Python!


----------------------------------------------------------------------

>Comment By: Brett Cannon (bcannon)
Date: 2003-05-12 16:48

Message:
Logged In: YES 
user_id=357491

I don't see this as worth cluttering up slice notation.  I like gaul's suggestion 
of using a list comprehension to build your list.  Heck, you can even simplify 
the list comp to ``[a[x] for x in b]``.  Yes, it is not as short as ``a(b)``, but 
writing it out it looks like ``[10, 20, 30, 40, 50, 60, 70, 80, 90][[0, 4, 5, 
7]]`` which just looks *really* cluttered to me.

You also have the built-in 'slice' if you need real control over your slices.  So 
you could do your ``a[0:4, 3:4, 0:-1, -1]`` example as ``[a[slice(*args)] for 
args in [(0,4), (3,4), (0,-1), (-1,)]]``.

God I love list comps.  =)

----------------------------------------------------------------------

Comment By: Andrew Gaul (gaul)
Date: 2001-07-14 15:35

Message:
Logged In: YES 
user_id=139865

Here's a function that gives one some of the functionality
you suggested:

>>> m=[10,20,30,40,50,60,70,80,90]
>>> n=[0,4,5,7]
>>> def dice(a, b):
...     return [ a[x] for x in xrange(len(a)) if x in b ]
...
>>> dice(m, n)
[10, 50, 60, 80]

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=355470&aid=419903&group_id=5470