Как вы используете синтаксис нарезки многоточием в Python?

Это появилось в скрытых функциях Python, но я не вижу хорошей документации или примеров, которые объясните, как работает эта функция.


person miracle2k    schedule 23.09.2008    source источник


Ответы (4)


Ellipsis или ... не является скрытой функцией, это просто константа. Это сильно отличается от, скажем, javascript ES6, где он является частью синтаксиса языка. Ни один встроенный класс или конструкция языка Python не используют его.

Таким образом, его синтаксис полностью зависит от вас или кого-то еще, написавшего код для его понимания.

Numpy использует его, как указано в документации. Некоторые примеры здесь.

В вашем собственном классе вы бы использовали это так:

>>> class TestEllipsis(object):
...     def __getitem__(self, item):
...         if item is Ellipsis:
...             return "Returning all items"
...         else:
...             return "return %r items" % item
... 
>>> x = TestEllipsis()
>>> print x[2]
return 2 items
>>> print x[...]
Returning all items

Конечно, есть документация по Python и справочник по языку. Но это не очень помогает.

person nosklo    schedule 23.09.2008
comment
выглядит совершенно неуместно, поскольку правильный способ сказать все элементы - ››› x [:] ››› x [:, 1: 2] - person Ronny; 08.05.2009
comment
@Ronny: Дело в том, чтобы продемонстрировать индивидуальное использование Ellipsis. - person nosklo; 08.05.2009
comment
Ссылки кажутся неработающими. - person SwiftsNamesake; 26.02.2015

Многоточие используется в numpy для нарезки многомерных структур данных.

Он предназначен для того, чтобы на данном этапе вставить столько полных фрагментов (:), чтобы расширить многомерный фрагмент до всех измерений.

Пример:

>>> from numpy import arange
>>> a = arange(16).reshape(2,2,2,2)

Теперь у вас есть 4-мерная матрица порядка 2x2x2x2. Чтобы выбрать все первые элементы в 4-м измерении, вы можете использовать многоточие.

>>> a[..., 0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

что эквивалентно

>>> a[:,:,:,0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

В ваших собственных реализациях вы можете игнорировать контракт, упомянутый выше, и использовать его по своему усмотрению.

person Torsten Marek    schedule 23.09.2008
comment
Возможно, я ошибаюсь, но разве a[:,:,:,0] вернет копию, а a[...,0] вернет представление, а не копию? Я пробовал запустить id() для обеих версий и для 3-мерного массива: a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] все имеют разные идентификаторы, тогда как: a[..., 0], a[..., 1], a[..., 2] все имеют одинаковые идентификаторы. - person mohitsharma44; 05.10.2016
comment
@ mohitsharma44 не на моей машине;) id() возвращает одинаковое значение для обоих. Также проверка с помощью __array_interface__['data'] показывает тот же адрес памяти. - person BoltzmannBrain; 30.03.2017
comment
Я считаю, что мы можем использовать a[indexes, ...], в то время как a даже является одномерным массивом! - person acgtyrant; 22.05.2017
comment
что такое 4-х мерная матрица? Имеет смысл называть его 4-х мерным массивом, а не матрицей. IMO. - person kmario23; 20.01.2018
comment
Эллипсы также полезны для нульмерных структур данных. Это единственный известный мне способ записи в скалярный numpy.ndarrays, например: my_scalar = np.asarray (3); my_scalar [...] = 5. Если вы выполните my_scalar [:] = 5, вы по праву получите ошибку, потому что нет измерения 0 для: для итерации. - person SuperElectric; 13.02.2018
comment
@SuperElectric Вы также можете использовать my_scalar.itemset (scalarvalue). Конечно, my_scalar [...] = scalar_value короче, но в приведенном выше комментарии вы сказали, что это единственный способ узнать. Просто даю альтернативу. - person kamathln; 02.03.2018

Это еще одно использование многоточия, которое не имеет ничего общего со срезами: я часто использую его во внутрипотоковом взаимодействии с очередями, как метку, сигнализирующую «Готово»; он есть, это объект, это синглтон, и его имя означает «недостаток», и это не чрезмерно используемый None (который может быть помещен в очередь как часть обычного потока данных). YMMV.

person tzot    schedule 23.09.2008
comment
Может быть, было бы яснее просто сказать: Done = object () где-нибудь и просто использовать это? - person Brandon Rhodes; 21.04.2009
comment
Не обязательно - это требует, чтобы вы действительно где-то сказали Done = object (). Значения Sentinel не обязательно плохая вещь - и использование почти бесполезных синглтонов Python в качестве часового не так уж и ужасно IMO (Ellipsis и () - это те, которые я использовал, где None не сбивает с толку). - person Rick Copeland; 22.06.2009
comment
Что касается Done = object (), я думаю, что лучше использовать многоточие, особенно если вы используете его для связи с очередями. Если вы перейдете от внутрипоточного к внутрипроцессному взаимодействию, идентификатор (Done) не будет таким же в другом процессе, и нет ничего, что могло бы отличить один объект от другого. Идентификатор многоточия тоже не будет таким же, но, по крайней мере, тип будет таким же - это точка синглтона. - person Tristan Reid; 18.01.2013
comment
Вопрос: Как использовать многоточие, но я считаю, что вы ошиблись. У него много толкований. Но я думаю, что правильный вопрос: как используется многоточие? т.е. какие шаги я должен предпринять, чтобы использовать многоточие в моем собственном коде. - person Lyndon White; 23.12.2014

Как указано в других ответах, его можно использовать для создания срезов. Полезно, когда вы не хотите писать много нотаций полных срезов (:) или когда вы просто не уверены в размерности обрабатываемого массива.

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

Пример:

>>> from numpy import arange
>>> a = arange(4).reshape(2,2)

Это приведет к ошибке:

>>> a[:,0,:]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: too many indices for array

Это будет работать:

a[...,0,:]
array([0, 1])
person Mauricio Perez    schedule 07.06.2018