“Slice lists” and “the ellipsis” in Python; slicing lists and lists of lists with lists of slices

StackOverflow https://stackoverflow.com/questions/1698753

  •  18-09-2019
  •  | 
  •  

Question

Original question: Can someone tell me how to use "slice lists" and the "ellipsis"? When are they useful? Thanks.

Here's what the language definition says about "slice_list" and "ellipsis"; Alex Martelli's answer points out their origin, which is not what I had envisioned.

[http://docs.python.org/reference/expressions.html#tok-slicing][1]

5.3.3. Slicings

extended_slicing ::= primary "[" slice_list "]"

slice_list ::= slice_item ("," slice_item)* [","]

slice_item ::= expression | proper_slice | ellipsis

ellipsis ::= "..."

[1]: http://docs.python.org/reference/expressions.html#tok-slicing

In case anyone (as I was) is looking for ways to attack a list (or a list of lists) with a list of slices, here are 5 ways to get a list of elements from a list that are selected by a list of slices and 2 ways to do the same thing to a list of lists, in that case applying one slice per list. The output's in a comment at the end. I find h5, the example that uses nested for loops, the hardest to understand if meaningful variable names aren't used (updated).

#!/usr/bin/env python



import itertools

puz = [(i + 100) for i in range(40)]
puz1 = list( puz)
puz2 = [(i + 200) for i in range(40)]
puz3 = [(i + 300) for i in range(40)]
puzs = [puz1,puz2,puz3]

sa = slice( 0,1,1)
sb = slice( 30,39,4)
sc = slice( -1, -15,-5)
ss = [sa,sb,sc]

def mapfunc( a,b):
    return a[b]

f = map( mapfunc,[puz] * len(ss),ss)
print "f =  ", f  #same as g below

g = [ puz[i]
    for i in ss ]
print "g =  ",g  #same as f, above

h1 = [ i 
    for i in itertools.chain( puz[sa],puz[sb],puz[sc]) ]
print "h1 = ", h1  #right 

h2 = [ i
    for i in itertools.chain( *(map( mapfunc,[puz] * len(ss),ss))) ]
print "h2 = ",h2  #right

h3 = [ i
    for i in itertools.chain( *f) ]
print "h3 = ",h3  #right

h4 = [ i 
    for i in itertools.chain( *g) ]
print "h4 = ", h4 #also right

h5 = []
for slice_object in ss:
    for list_element in puz[slice_object]:
        h5.append( list_element)
print "h5 = ", h5  #right, too

print "=============================="

hh1 = [ i
    for i in itertools.chain( *(map( mapfunc,puzs,ss))) ]
print "hh1 =  ",hh1  #right

puz_s_pairs = zip( puzs,ss)
#print "puz_s_pairs = ",puz_s_pairs
hh2 = [ i
    for i in itertools.chain( *(map( mapfunc,*zip( *puz_s_pairs)))) ]
print "hh2 =  ",hh2  #right

'''
>>> execfile(r'D:/cygwin/home/usr01/wrk/py/pyexpts/list_of_slices_of_list.02.py')
f =   [[100], [130, 134, 138], [139, 134, 129]]
g =   [[100], [130, 134, 138], [139, 134, 129]]
h1 =  [100, 130, 134, 138, 139, 134, 129]
h2 =  [100, 130, 134, 138, 139, 134, 129]
h3 =  [100, 130, 134, 138, 139, 134, 129]
h4 =  [100, 130, 134, 138, 139, 134, 129]
h5 =  [100, 130, 134, 138, 139, 134, 129]
==============================
hh1 =   [100, 230, 234, 238, 339, 334, 329]
hh2 =   [100, 230, 234, 238, 339, 334, 329]
'''
Was it helpful?

Solution

Slice lists and ellipsis were originally introduced in Python to supply nice syntax sugar for the precedessor of numpy (good old Numeric). If you're using numpy (no reason to go back to any of its predecessors!-) you should of course use them; if for whatever strange reason you're doing your own implementation of super-flexible multi-dimensional arrays, you'll definitely want to study the way numpy uses them and probably imitate it closely (it is pretty well designed after all). I can't think of good uses beyond multi-dimensional arrays.

OTHER TIPS

Numpy uses them to implement array slicing.

I'm not too sure about ellipsis, so I will not address that, lest I give you a bad answer.

Here goes list slicing:

I hope you know that list indeces begin at 0.

l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Indexing into a list:

l[0]
>>> 0

l[5]
>>> 5

Slicing a list. The first index is included, but not the last:

l[0:5]
>>> [0, 1, 2, 3, 4]

l[2:5]
>>> [2, 3, 4]

Return the whole list as ONE slice:

l[:]
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Get a slice of the list containing every element including and after the 3rd index:

l[3:]
>>> [3, 4, 5, 6, 7, 8, 9]

Get a slice of the list containing every element upto but not including the 5th index:

l[:5]
>>> [0, 1, 2, 3, 4]

Here is something that you would not expect python to do:

l[5:18]  # note: there is no 18th index in this list
>>> [5, 6, 7, 8, 9]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top