Оригинальный вопрос: может кто-нибудь сказать мне, как использовать «списки срезов» и «многоточие»? Когда они полезны? Спасибо.

Вот что говорит определение языка о «slice_list» и «ellipsis»; Ответ Алекса Мартелли указывает на их происхождение, а это не то, что я предполагал.

[http://docs.python.org/reference/expressions .html # ТОК- нарезка ] [ 1 ]

5.3.3 . разрезаниях

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

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

slice_item :: = выражение | Proper_slice | эллипсис

многоточие :: = "..."

[ 1 ] : http://docs.python.org/reference/expressions.html#tok- нарезка

В случае, если кто-то (как я) ищет способы атаковать список (или список списков) списком срезов, вот 5 способов получить список элементов из списка, которые выбраны списком срезов и 2 способа сделать то же самое со списком списков, в этом случае применяя один срез на список. Вывод в комментарии в конце. Я считаю, что h5, пример, который использует вложенные циклы, труднее всего понять, если значимые имена переменных не используются (обновлено).

#!/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]
'''
2
behindthefall 9 Ноя 2009 в 05:01

3 ответа

Лучший ответ

Списки слайсов и многоточие были первоначально введены в Python, чтобы обеспечить хороший синтаксический сахар для предшественника numpy (старый добрый Numeric). Если вы используете numpy (нет причин возвращаться к любому из его предшественников! -), вы, конечно, должны их использовать; если по какой-то странной причине вы делаете свою собственную реализацию сверхгибких многомерных массивов, вам определенно захочется изучить, как Numpy использует их, и, вероятно, подражать им (это довольно хорошо ) разработан в конце концов). Я не могу думать о хорошем использовании за пределами многомерных массивов.

11
Alex Martelli 9 Ноя 2009 в 05:13
Ах. Таким образом, я не должен думать о «списках срезов» как о способе избавиться от произвольных множественных прогонов списков в одном компактном выражении. Жалость. Мне это почти пригодилось.
 – 
behindthefall
9 Ноя 2009 в 05:26
Для «прогонов списков» следует читать «прогоны из одного одномерного списка».
 – 
behindthefall
9 Ноя 2009 в 05:27
1
@behindthefalls, нет, прогоны обычно извлекаются с помощью itertools.groupby - специального синтаксиса для этого нет. Вы, конечно, могли бы реализовать такой синтаксис в своих собственных объектах, хотя не уверен, что он будет так удобен для чтения для большинства людей.
 – 
Alex Martelli
9 Ноя 2009 в 05:42
Алекс, спасибо за подсказку itertools.groupby: я никогда не замечал эту операцию, но пойду посмотрю. Я ценю вашу помощь. Я пытаюсь понять код, который написал 4 года назад, и (надеюсь) упрощаю множество циклов списков / наборов. Мне пришло в голову, что я мог бы предварительно упаковать некоторые вещи в виде фрагментов или списков фрагментов - если это было законно. Вернуться к доске для рисования.
 – 
behindthefall
9 Ноя 2009 в 06:46
Itertools.groupby делает что-то другое, но есть несколько способов заставить списки срезов работать должным образом. Бедный список никогда не знал, что его поразило. Теперь, если я могу получить список фрагментов для работы со списком списков ...
 – 
behindthefall
9 Ноя 2009 в 08:53

Numpy использует их для реализации нарезки массивов.

3
Ned Batchelder 9 Ноя 2009 в 05:03
2
Многоточие - используется редко. Нарезка - обычная.
 – 
S.Lott
9 Ноя 2009 в 05:11

Я не слишком уверен насчет многоточия, поэтому я не буду обращать на это внимание, чтобы не дать вам плохой ответ.

Здесь идет нарезка списка:

Я надеюсь, что вы знаете, что индексы списка начинаются с 0.

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

Индексирование в список:

l[0]
>>> 0

l[5]
>>> 5

Нарезка списка. Первый индекс включен, но не последний:

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

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

Вернуть весь список как ОДИН срез:

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

Получить часть списка, содержащего каждый элемент, включая и после 3-го индекса:

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

Получить часть списка, содержащего каждый элемент до, но не включая 5-й индекс:

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

Вот что вы не ожидаете от Python:

l[5:18]  # note: there is no 18th index in this list
>>> [5, 6, 7, 8, 9]
1
inspectorG4dget 9 Ноя 2009 в 05:13
1
Обратите внимание, что опция l [:] - это сокращение для копирования массива, и вы будете видеть это довольно часто.
 – 
Karl Guertin
9 Ноя 2009 в 05:27
Меня озадачивает, когда я сталкиваюсь с тем, что язык позволяет вам иметь два или более выражений среза, разделенных запятыми! ;-)
 – 
behindthefall
9 Ноя 2009 в 05:29