Подтвердить что ты не робот

Python slice how-to, я знаю кусочек Python, но как я могу использовать для этого встроенный объект slice?

Как использовать встроенную функцию slice и как ее использовать?
Я знаю, как прямая дорога питонской нарезки - l1[start:stop:step]. Я хочу знать, есть ли у меня объект среза, тогда как его использовать?

4b9b3361

Ответ 1

Вы создаете срез, вызывая срез с теми же полями, которые вы использовали бы при записи [start: end: step]:

sl = slice(0,4)

Чтобы использовать срез, просто передайте его, как если бы он был индексом в список или строку:

>>> s = "ABCDEFGHIJKL"
>>> sl = slice(0,4)
>>> print(s[sl])
'ABCD'

Скажем, у вас есть файл текстовых полей фиксированной длины. Вы можете определить список срезов, чтобы легко извлекать значения из каждой "записи" в этом файле.

data = """\
0010GEORGE JETSON    12345 SPACESHIP ST   HOUSTON       TX
0020WILE E COYOTE    312 ACME BLVD        TUCSON        AZ
0030FRED FLINTSTONE  246 GRANITE LANE     BEDROCK       CA
0040JONNY QUEST      31416 SCIENCE AVE    PALO ALTO     CA""".splitlines()


fieldslices = [slice(*fielddef) for fielddef in [
    (0,4), (4, 21), (21,42), (42,56), (56,58),
    ]]
fields = "id name address city state".split()

for rec in data:
    for field,sl in zip(fields, fieldslices):
        print("{} : {}".format(field, rec[sl]))
    print('')

Печать

id : 0010
name : GEORGE JETSON    
address : 12345 SPACESHIP ST   
city : HOUSTON       
state : TX

id : 0020
name : WILE E COYOTE    
address : 312 ACME BLVD        
city : TUCSON        
state : AZ

id : 0030
name : FRED FLINTSTONE  
address : 246 GRANITE LANE     
city : BEDROCK       
state : CA

id : 0040
name : JONNY QUEST      
address : 31416 SCIENCE AVE    
city : PALO ALTO     
state : CA

Ответ 2

Квадратные скобки после последовательности обозначают либо индексацию, либо нарезку в зависимости от того, что внутри скобок:

>>> "Python rocks"[1]    # index
'y'
>>> "Python rocks"[1:10:2]    # slice
'yhnrc'

Оба этих случая обрабатываются методом __getitem__() последовательности (или __setitem__(), если слева от знака равенства). Индекс или срез передается методам в виде единственного аргумента, и способ Python делает это путем преобразования нотации среза (1:10:2 в этом случае) в объект среза: slice(1,10,2).

Итак, если вы определяете свой собственный подобный последовательности класс или переопределяете методы __getitem__ или __setitem__ или __delitem__ другого класса, вам нужно проверить аргумент индекса, чтобы определить, является ли это int или slice и обрабатывать соответственно:

def __getitem__(self, index):
    if isinstance(index, int):
        ...    # process index as an integer
    elif isinstance(index, slice):
        start, stop, step = index.indices(len(self))    # index is a slice
        ...    # process slice
    else:
        raise TypeError("index must be int or slice")

Объект A slice имеет три атрибута: start, stop и step, а один метод: indices, который принимает один аргумент, длину объекта и возвращает 3-кортеж: (start, stop, step).

Ответ 3

>>> class sl:
...  def __getitem__(self, *keys): print keys
...     
>>> s = sl()
>>> s[1:3:5]
(slice(1, 3, 5),)
>>> s[1:2:3, 1, 4:5]
((slice(1, 2, 3), 1, slice(4, 5, None)),)
>>>

Ответ 4

Функция slice возвращает объекты среза. Объекты среза являются одним из внутренних типов Python, которые оптимизированы для производительности чтения - все их атрибуты доступны только для чтения.

Изменение slice может быть полезно, если вы хотите изменить поведение по умолчанию. Например, lxml использует нотацию фрагментов для доступа к элементам DOM (однако я не подтвердил, как они это сделали).

Ответ 5

Пытаясь ответить на подмножество строки, основанной на переменной, я вспомнил, что у numpy есть синтаксически хороший способ определения объектов срезов:

>>> import numpy as np
>>> s = "The long-string instrument is a musical instrument in which the string is of such a length that the fundamental transverse wave is below what a person can hear as a tone."
>>> z = np.s_[18:26]  # in this case same as slice(18, 26, None)
>>> s[z]
'strument'

Решаемая здесь проблема заключается в том, как сохранить срез в переменной для последующего использования, и np.s_ позволяет это сделать. Да, он не является встроенным, но поскольку этот оригинальный вопрос был перенаправлен сюда, я чувствую, что мой ответ также относится и к этому. Кроме того, numpy был одной из причин, по которой в Python, IIRC были добавлены столь продвинутые возможности нарезки.

Пример более сложной "нарезки":

>>> data = np.array(range(6)).reshape((2, 3))
>>> z = np.s_[:1, 1:2]
>>> data[z]
array([[1]])
>>> data
array([[0, 1, 2],
       [3, 4, 5]])
>>> z
(slice(None, 1, None), slice(1, 2, None))

где z теперь кортеж кусочков.