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%5D%5B1%5D
5.3.3. Slicings
extended_slicing ::= primary “[”
slice_list “]”slice_list ::= slice_item (“,”
slice_item)* [“,”]slice_item ::= expression |
proper_slice | ellipsisellipsis ::= “…”
[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]
'''
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.