Python slice how-to, znam Python slice, ale jak mogę użyć do tego wbudowanego obiektu slice?

Jaki jest pożytek z wbudowanej funkcji slice i jak mogę jej używać?
Bezpośredni sposób cięcia Pythonicznego znam - l1[start:stop:step]. Chcę wiedzieć, czy mam obiekt slice, jak go używać?

Author: Michael Petrotta, 2010-10-12

4 answers

Tworzysz slice, wywołując slice z tymi samymi polami, których użyjesz, wykonując notację [start :end: step]:

sl = slice(0,4)

Aby użyć plasterka, po prostu przekaż go tak, jakby był indeksem do listy lub łańcucha znaków:

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

Załóżmy, że masz plik pól tekstowych o stałej długości. Możesz zdefiniować listę plasterków, aby łatwo wyodrębnić wartości z każdego "rekordu" w tym pliku.

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('')

Druki:

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
 80
Author: PaulMcG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-04 14:16:09

Nawiasy kwadratowe po sekwencji oznaczają indeksowanie lub krojenie w zależności od tego, co znajduje się w nawiasach:

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

Oba te przypadki są obsługiwane metodą __getitem__() sekwencji (lub __setitem__() Jeśli po lewej stronie znaku równości.) Indeks lub slice są przekazywane do metod jako pojedynczy argument, a sposób, w jaki Python to robi, polega na przekonwertowaniu notacji slice (1:10:2, w tym przypadku) na obiekt slice: slice(1,10,2).

Więc jeśli definiujesz własną klasę podobną do sekwencji lub nadpisując __getitem__ lub __setitem__ lub __delitem__ metody innej klasy, musisz przetestować argument index, aby określić, czy jest on int lub slice, i odpowiednio przetworzyć:

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 obiekt posiada trzy atrybuty: start, stop i step, oraz jedna metoda: indices, która pobiera pojedynczy argument, długość obiektu i zwraca 3-krotkę: (start, stop, step).

 32
Author: Don O'Donnell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-12 06:16:45
>>> 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)),)
>>>
 6
Author: SingleNegationElimination,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-10 16:01:59

The slice funkcja zwraca obiekty slice . Obiekty Slice są jednym z wewnętrznych typów Pythona, które są zoptymalizowane pod kątem wydajności odczytu - wszystkie ich atrybuty są tylko do odczytu.

Zmiana slice może być przydatna, jeśli chcesz zmienić domyślne zachowanie. Na przykład, lxml używa notacji slice, aby uzyskać dostęp do elementów DOM (jednak nie potwierdziłem, jak to zrobili).

 3
Author: Tim McNamara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-12 03:49:06