Respostas:
Na verdade, é bem simples:
a[start:stop] # items start through stop-1
a[start:] # items start through the rest of the array
a[:stop] # items from the beginning through stop-1
a[:] # a copy of the whole array
Há também o step
valor, que pode ser usado com qualquer um dos itens acima:
a[start:stop:step] # start through not past stop, by step
O ponto principal a lembrar é que o :stop
valor representa o primeiro valor que não está na fatia selecionada. Portanto, a diferença entre stop
e start
é o número de elementos selecionados (se step
for 1, o padrão).
O outro recurso é esse start
ou stop
pode ser um número negativo , o que significa que conta desde o final da matriz em vez do início. Assim:
a[-1] # last item in the array
a[-2:] # last two items in the array
a[:-2] # everything except the last two items
Da mesma forma, step
pode ser um número negativo:
a[::-1] # all items in the array, reversed
a[1::-1] # the first two items, reversed
a[:-3:-1] # the last two items, reversed
a[-3::-1] # everything except the last two items, reversed
Python é gentil com o programador se houver menos itens do que você solicita. Por exemplo, se você solicitar a[:-2]
e a
contiver apenas um elemento, obterá uma lista vazia em vez de um erro. Às vezes você prefere o erro, portanto, saiba que isso pode acontecer.
slice()
objetoO operador de fatiamento []
está realmente sendo usado no código acima com um slice()
objeto usando a :
notação (que é válida apenas dentro []
), ou seja:
a[start:stop:step]
é equivalente a:
a[slice(start, stop, step)]
Os objetos de fatia também se comportam de maneira ligeiramente diferente, dependendo do número de argumentos, da mesma forma que range()
, por exemplo , ambos slice(stop)
e slice(start, stop[, step])
são suportados. Para pular a especificação de um determinado argumento, pode-se usar None
, de modo que, por exemplo, a[start:]
seja equivalente a a[slice(start, None)]
ou a[::-1]
seja a[slice(None, None, -1)]
.
Embora a :
notação baseada em seja muito útil para o fatiamento simples, o uso explícito de slice()
objetos simplifica a geração programática do fatiamento.
None
qualquer um dos espaços vazios. Por exemplo, [None:None]
faz uma cópia inteira. Isso é útil quando você precisa especificar o final do intervalo usando uma variável e precisa incluir o último item.
del
faz a notação de fatia wrt. Em particular, del arr[:]
não é imediatamente óbvio ( "arr [:] faz uma cópia, o mesmo acontece del exclusão que copiar ???" etc.)
O tutorial do Python fala sobre isso (role um pouco para baixo até chegar à parte sobre fatiar).
O diagrama de arte ASCII também é útil para lembrar como as fatias funcionam:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
Uma maneira de lembrar como as fatias funcionam é pensar nos índices como apontando entre os caracteres, com a borda esquerda do primeiro caractere numerada 0. Então, a borda direita do último caractere de uma seqüência de n caracteres tem o índice n .
a[-4,-6,-1]
ser, yP
mas é ty
. O que sempre funciona é pensar em caracteres ou slots e usar a indexação como um intervalo semiaberto - abertura à direita se for positivo, abertura à esquerda se for um passo negativo.
x[:0]
acontece quando se inicia do início), então você precisa criar matrizes pequenas para casos especiais. : /
Enumerando as possibilidades permitidas pela gramática:
>>> seq[:] # [seq[0], seq[1], ..., seq[-1] ]
>>> seq[low:] # [seq[low], seq[low+1], ..., seq[-1] ]
>>> seq[:high] # [seq[0], seq[1], ..., seq[high-1]]
>>> seq[low:high] # [seq[low], seq[low+1], ..., seq[high-1]]
>>> seq[::stride] # [seq[0], seq[stride], ..., seq[-1] ]
>>> seq[low::stride] # [seq[low], seq[low+stride], ..., seq[-1] ]
>>> seq[:high:stride] # [seq[0], seq[stride], ..., seq[high-1]]
>>> seq[low:high:stride] # [seq[low], seq[low+stride], ..., seq[high-1]]
Claro se (high-low)%stride != 0
, então o ponto final será um pouco menor que high-1
.
E se stride
for negativo, a ordem será alterada um pouco, pois estamos em contagem regressiva:
>>> seq[::-stride] # [seq[-1], seq[-1-stride], ..., seq[0] ]
>>> seq[high::-stride] # [seq[high], seq[high-stride], ..., seq[0] ]
>>> seq[:low:-stride] # [seq[-1], seq[-1-stride], ..., seq[low+1]]
>>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]]
Fatias estendidas (com vírgulas e elipses) são usadas principalmente apenas por estruturas de dados especiais (como NumPy); as seqüências básicas não as suportam.
>>> class slicee:
... def __getitem__(self, item):
... return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
repr
__getitem__
é; seu exemplo é equivalente a apple[slice(4, -4, -1)]
.
As respostas acima não discutem a atribuição de fatia. Para entender a atribuição de fatia, é útil adicionar outro conceito à arte ASCII:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
Slice position: 0 1 2 3 4 5 6
Index position: 0 1 2 3 4 5
>>> p = ['P','y','t','h','o','n']
# Why the two sets of numbers:
# indexing gives items, not lists
>>> p[0]
'P'
>>> p[5]
'n'
# Slicing gives lists
>>> p[0:1]
['P']
>>> p[0:2]
['P','y']
Uma heurística é, para uma fatia de zero a n, pense: "zero é o começo, comece do começo e coloque n itens em uma lista".
>>> p[5] # the last of six items, indexed from zero
'n'
>>> p[0:5] # does NOT include the last item!
['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
['P','y','t','h','o','n']
Outra heurística é: "para qualquer fatia, substitua o início por zero, aplique a heurística anterior para chegar ao final da lista e conte o primeiro número de volta para cortar os itens do início"
>>> p[0:4] # Start at the beginning and count out 4 items
['P','y','t','h']
>>> p[1:4] # Take one item off the front
['y','t','h']
>>> p[2:4] # Take two items off the front
['t','h']
# etc.
A primeira regra da atribuição de fatia é que, como a fatia retorna uma lista, a atribuição de fatia exige uma lista (ou outra iterável):
>>> p[2:3]
['t']
>>> p[2:3] = ['T']
>>> p
['P','y','T','h','o','n']
>>> p[2:3] = 't'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
A segunda regra de atribuição de fatia, que você também pode ver acima, é que qualquer parte da lista é retornada pela indexação de fatia, é a mesma parte que é alterada pela atribuição de fatia:
>>> p[2:4]
['T','h']
>>> p[2:4] = ['t','r']
>>> p
['P','y','t','r','o','n']
A terceira regra de atribuição de fatia é que a lista atribuída (iterável) não precisa ter o mesmo comprimento; a fatia indexada é simplesmente cortada e substituída em massa pelo que estiver sendo atribuído:
>>> p = ['P','y','t','h','o','n'] # Start over
>>> p[2:4] = ['s','p','a','m']
>>> p
['P','y','s','p','a','m','o','n']
A parte mais difícil de se acostumar é a atribuição de fatias vazias. Usando as heurísticas 1 e 2, é fácil indexar uma fatia vazia:
>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
['P','y','t','h']
>>> p[1:4]
['y','t','h']
>>> p[2:4]
['t','h']
>>> p[3:4]
['h']
>>> p[4:4]
[]
E depois que você vê isso, a atribuição de fatia à fatia vazia também faz sentido:
>>> p = ['P','y','t','h','o','n']
>>> p[2:4] = ['x','y'] # Assigned list is same length as slice
>>> p
['P','y','x','y','o','n'] # Result is same length
>>> p = ['P','y','t','h','o','n']
>>> p[3:4] = ['x','y'] # Assigned list is longer than slice
>>> p
['P','y','t','x','y','o','n'] # The result is longer
>>> p = ['P','y','t','h','o','n']
>>> p[4:4] = ['x','y']
>>> p
['P','y','t','h','x','y','o','n'] # The result is longer still
Observe que, como não estamos alterando o segundo número da fatia (4), os itens inseridos sempre se comparam com o 'o', mesmo quando estamos atribuindo a fatia vazia. Portanto, a posição para a atribuição de fatia vazia é a extensão lógica das posições para as atribuições de fatia não vazias.
Fazendo um backup, o que acontece quando você continua com nossa procissão de contagem do início da fatia?
>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
['P','y','t','h']
>>> p[1:4]
['y','t','h']
>>> p[2:4]
['t','h']
>>> p[3:4]
['h']
>>> p[4:4]
[]
>>> p[5:4]
[]
>>> p[6:4]
[]
Com a fatia, uma vez que você termina, você termina; não começa a cortar para trás. No Python, você não obtém avanços negativos, a menos que você os solicite explicitamente usando um número negativo.
>>> p[5:3:-1]
['n','o']
Existem algumas consequências estranhas na regra "quando terminar, pronto":
>>> p[4:4]
[]
>>> p[5:4]
[]
>>> p[6:4]
[]
>>> p[6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
De fato, comparado à indexação, o fatiamento do Python é bizarramente à prova de erros:
>>> p[100:200]
[]
>>> p[int(2e99):int(1e99)]
[]
Às vezes, isso pode ser útil, mas também pode levar a um comportamento estranho:
>>> p
['P', 'y', 't', 'h', 'o', 'n']
>>> p[int(2e99):int(1e99)] = ['p','o','w','e','r']
>>> p
['P', 'y', 't', 'h', 'o', 'n', 'p', 'o', 'w', 'e', 'r']
Dependendo da sua aplicação, isso pode ... ou não ... ser o que você estava esperando lá!
Abaixo está o texto da minha resposta original. Tem sido útil para muitas pessoas, então eu não queria excluí-lo.
>>> r=[1,2,3,4]
>>> r[1:1]
[]
>>> r[1:1]=[9,8]
>>> r
[1, 9, 8, 2, 3, 4]
>>> r[1:1]=['blah']
>>> r
[1, 'blah', 9, 8, 2, 3, 4]
Isso também pode esclarecer a diferença entre fatiar e indexar.
Explicar a notação de fatia do Python
Em suma, os pontos ( :
) em notação subscrita ( subscriptable[subscriptarg]
) Faz notação slice - que tem os argumentos opcionais, start
, stop
, step
:
sliceable[start:stop:step]
A fatia de Python é uma maneira computacionalmente rápida de acessar metodicamente partes de seus dados. Na minha opinião, para ser um programador intermediário de Python, é um aspecto da linguagem com a qual é necessário estar familiarizado.
Para começar, vamos definir alguns termos:
start: o índice inicial da fatia, incluirá o elemento nesse índice, a menos que seja o mesmo que stop , o padrão é 0, ou seja, o primeiro índice. Se for negativo, significa iniciar
n
itens a partir do final.stop: o índice final da fatia, ele não inclui o elemento nesse índice, o padrão é o comprimento da sequência cortada, ou seja, até e incluindo o final.
passo: a quantidade pela qual o índice aumenta, o padrão é 1. Se for negativo, você estará fatiando o iterável ao contrário.
Você pode criar qualquer um desses números positivos ou negativos. O significado dos números positivos é simples, mas para números negativos, assim como índices em Python, você contar para trás a partir do final para o início e parada , e para a etapa , você simplesmente diminuir o seu índice. Este exemplo é do tutorial da documentação , mas eu o modifiquei um pouco para indicar qual item de uma sequência cada índice faz referência:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
Para usar a notação de fatia com uma sequência que a suporta, você deve incluir pelo menos um dois pontos entre colchetes que seguem a sequência (que realmente implementa o __getitem__
método da sequência, de acordo com o modelo de dados Python ).
A notação de fatia funciona assim:
sequence[start:stop:step]
E lembre-se de que existem padrões para iniciar , parar e etapa , para acessar os padrões, simplesmente deixe de fora o argumento.
A notação de fatia para obter os últimos nove elementos de uma lista (ou qualquer outra sequência que a suporte, como uma string) ficaria assim:
my_list[-9:]
Quando vejo isso, li a parte entre parênteses como "9ª do fim até o fim". (Na verdade, eu abrevio isso mentalmente como "-9, em")
A notação completa é
my_list[-9:None:None]
e para substituir os padrões (na verdade, quando step
é negativo, stop
o padrão é -len(my_list) - 1
, portanto, None
para parar realmente significa que ele vai para a etapa final que leva):
my_list[-9:len(my_list):1]
O cólon , :
, é o que diz ao Python que você está dando-lhe uma fatia e não um índice regular. É por isso que a maneira idiomática de fazer uma cópia superficial das listas no Python 2 é
list_copy = sequence[:]
E limpá-los é com:
del my_list[:]
(Python 3 obtém um método list.copy
e list.clear
.)
step
negativo, os padrões start
e as stop
alterações sãoPor padrão, quando o step
argumento está vazio (ou None
), é atribuído a +1
.
Mas você pode passar um número inteiro negativo e a lista (ou a maioria das outras slicables padrão) será cortada do fim ao começo.
Assim, uma fatia negativa alterará os padrões para start
estop
!
Eu gosto de incentivar os usuários a lerem a fonte e a documentação. O código fonte dos objetos de fatia e essa lógica são encontrados aqui . Primeiro, determinamos se step
é negativo:
step_is_negative = step_sign < 0;
Nesse caso, o limite inferior -1
significa que cortamos todo o caminho até o início, inclusive, e o limite superior é o comprimento menos 1, o que significa que começamos no final. (Observe que a semântica disso -1
é diferente da -1
que os usuários podem passar índices no Python, indicando o último item.)
if (step_is_negative) { lower = PyLong_FromLong(-1L); if (lower == NULL) goto error; upper = PyNumber_Add(length, lower); if (upper == NULL) goto error; }
Caso contrário, step
é positivo, e o limite inferior será zero e o limite superior (que subimos, mas não incluindo) o comprimento da lista fatiada.
else { lower = _PyLong_Zero; Py_INCREF(lower); upper = length; Py_INCREF(upper); }
Então, talvez seja necessário aplicar os padrões para start
e stop
- o padrão então para start
é calculado como o limite superior quando step
for negativo:
if (self->start == Py_None) { start = step_is_negative ? upper : lower; Py_INCREF(start); }
e stop
, o limite inferior:
if (self->stop == Py_None) { stop = step_is_negative ? lower : upper; Py_INCREF(stop); }
Você pode achar útil separar a formação da fatia da passagem para o list.__getitem__
método ( é isso que os colchetes fazem ). Mesmo se você não é novo nele, ele mantém seu código mais legível, para que outras pessoas que precisam ler seu código possam entender mais facilmente o que está fazendo.
No entanto, você não pode simplesmente atribuir alguns números inteiros separados por dois pontos a uma variável. Você precisa usar o objeto de fatia:
last_nine_slice = slice(-9, None)
O segundo argumento,, None
é necessário, para que o primeiro argumento seja interpretado como o start
argumento, caso contrário, seria o stop
argumento .
Você pode passar o objeto de fatia para sua sequência:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
É interessante que os intervalos também tomem fatias:
>>> range(100)[last_nine_slice]
range(91, 100)
Como fatias de listas Python criam novos objetos na memória, outra função importante a ser observada é itertools.islice
. Normalmente, você deseja iterar sobre uma fatia, e não apenas criar estaticamente na memória. islice
é perfeito para isso. Uma ressalva, ele não suporta argumentos negativos para start
, stop
ou step
, portanto, se esse é um problema, pode ser necessário calcular índices ou reverter o iterável antecipadamente.
length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)
e agora:
>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]
O fato de as fatias da lista fazerem uma cópia é um recurso das próprias listas. Se você estiver cortando objetos avançados como um DataFrame do Pandas, ele poderá retornar uma exibição no original, e não uma cópia.
E algumas coisas que não eram imediatamente óbvias para mim quando vi a sintaxe da fatia:
>>> x = [1,2,3,4,5,6]
>>> x[::-1]
[6,5,4,3,2,1]
Maneira fácil de reverter seqüências!
E se você quisesse, por algum motivo, cada segundo item na sequência reversa:
>>> x = [1,2,3,4,5,6]
>>> x[::-2]
[6,4,2]
No Python 2.7
Corte em Python
[a:b:c]
len = length of string, tuple or list
c -- default is +1. The sign of c indicates forward or backward, absolute value of c indicates steps. Default is forward with step size 1. Positive means forward, negative means backward.
a -- When c is positive or blank, default is 0. When c is negative, default is -1.
b -- When c is positive or blank, default is len. When c is negative, default is -(len+1).
Compreender a atribuição de índice é muito importante.
In forward direction, starts at 0 and ends at len-1
In backward direction, starts at -1 and ends at -len
Quando você diz [a: b: c], está dizendo que, dependendo do sinal de c (para frente ou para trás), comece em a e termine em b (excluindo o elemento no b-ésimo índice). Use a regra de indexação acima e lembre-se de que você encontrará apenas elementos neste intervalo:
-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1
Mas esse intervalo continua nas duas direções infinitamente:
...,-len -2 ,-len-1,-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1, len, len +1, len+2 , ....
Por exemplo:
0 1 2 3 4 5 6 7 8 9 10 11
a s t r i n g
-9 -8 -7 -6 -5 -4 -3 -2 -1
Se sua escolha de a, bec permitir sobreposição com o intervalo acima, conforme você percorre as regras de a, b, c acima, você obterá uma lista com elementos (tocados durante a travessia) ou obterá uma lista vazia.
Uma última coisa: se aeb são iguais, você também recebe uma lista vazia:
>>> l1
[2, 3, 4]
>>> l1[:]
[2, 3, 4]
>>> l1[::-1] # a default is -1 , b default is -(len+1)
[4, 3, 2]
>>> l1[:-4:-1] # a default is -1
[4, 3, 2]
>>> l1[:-3:-1] # a default is -1
[4, 3]
>>> l1[::] # c default is +1, so a default is 0, b default is len
[2, 3, 4]
>>> l1[::-1] # c is -1 , so a default is -1 and b default is -(len+1)
[4, 3, 2]
>>> l1[-100:-200:-1] # Interesting
[]
>>> l1[-1:-200:-1] # Interesting
[4, 3, 2]
>>> l1[-1:-1:1]
[]
>>> l1[-1:5:1] # Interesting
[4]
>>> l1[1:-7:1]
[]
>>> l1[1:-7:-1] # Interesting
[3, 2]
>>> l1[:-2:-2] # a default is -1, stop(b) at -2 , step(c) by 2 in reverse direction
[4]
a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]; a[:-2:-2]
que resulta em[9]
Encontrei esta excelente tabela em http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
Python indexes and slices for a six-element list.
Indexes enumerate the elements, slices enumerate the spaces between the elements.
Index from rear: -6 -5 -4 -3 -2 -1 a=[0,1,2,3,4,5] a[1:]==[1,2,3,4,5]
Index from front: 0 1 2 3 4 5 len(a)==6 a[:5]==[0,1,2,3,4]
+---+---+---+---+---+---+ a[0]==0 a[:-2]==[0,1,2,3]
| a | b | c | d | e | f | a[5]==5 a[1:2]==[1]
+---+---+---+---+---+---+ a[-1]==5 a[1:-1]==[1,2,3,4]
Slice from front: : 1 2 3 4 5 : a[-2]==4
Slice from rear: : -5 -4 -3 -2 -1 :
b=a[:]
b==[0,1,2,3,4,5] (shallow copy of a)
Depois de usá-lo um pouco, percebo que a descrição mais simples é que é exatamente o mesmo que os argumentos em um for
loop ...
(from:to:step)
Qualquer um deles é opcional:
(:to:step)
(from::step)
(from:to)
Em seguida, a indexação negativa precisa apenas que você adicione o comprimento da sequência aos índices negativos para entendê-la.
Isso funciona para mim de qualquer maneira ...
Acho mais fácil lembrar como funciona e, em seguida, posso descobrir qualquer combinação específica de início / parada / etapa.
É instrutivo entender range()
primeiro:
def range(start=0, stop, step=1): # Illegal syntax, but that's the effect
i = start
while (i < stop if step > 0 else i > stop):
yield i
i += step
Comece de start
, incremente por step
, não alcance stop
. Muito simples.
O que deve ser lembrado sobre o passo negativo é que esse stop
é sempre o fim excluído, seja ele maior ou menor. Se você deseja a mesma fatia na ordem oposta, é muito mais fácil fazer a reversão separadamente: por exemplo, 'abcde'[1:-2][::-1]
corta um caractere da esquerda, dois da direita e depois inverte. (Veja também reversed()
.)
O fatiamento da sequência é o mesmo, exceto que ele normaliza primeiro os índices negativos e nunca pode sair da sequência:
TODO : O código abaixo tinha um erro com "nunca sair da sequência" quando abs (etapa)> 1; Eu acho que o corrigi para estar correto, mas é difícil de entender.
def this_is_how_slicing_works(seq, start=None, stop=None, step=1):
if start is None:
start = (0 if step > 0 else len(seq)-1)
elif start < 0:
start += len(seq)
if not 0 <= start < len(seq): # clip if still outside bounds
start = (0 if step > 0 else len(seq)-1)
if stop is None:
stop = (len(seq) if step > 0 else -1) # really -1, not last element
elif stop < 0:
stop += len(seq)
for i in range(start, stop, step):
if 0 <= i < len(seq):
yield seq[i]
Não se preocupe com os is None
detalhes - lembre-se de que a omissão start
e / ou stop
sempre faz a coisa certa para fornecer toda a sequência.
A normalização de índices negativos primeiro permite que o início e / ou a parada sejam contados a partir do final independentemente: 'abcde'[1:-2] == 'abcde'[1:3] == 'bc'
apesar range(1,-2) == []
. Às vezes, a normalização é considerada "módulo do comprimento", mas observe que ele adiciona o comprimento apenas uma vez: por exemplo, 'abcde'[-53:42]
é apenas a string inteira.
this_is_how_slicing_works
é o mesmo que fatia python. O EG [0, 1, 2][-5:3:3]
obterá [0] em python, mas list(this_is_how_slicing_works([0, 1, 2], -5, 3, 3))
obterá [1].
range(4)[-200:200:3] == [0, 3]
mas list(this_is_how_slicing_works([0, 1, 2, 3], -200, 200, 3)) == [2]
. Meu if 0 <= i < len(seq):
foi uma tentativa de implementar "nunca saia da sequência" simplesmente, mas está errado na etapa> 1. Vou reescrevê-lo hoje mais tarde (com testes).
Eu mesmo uso o método "um índice aponta entre elementos" para pensar sobre isso, mas uma maneira de descrevê-lo que às vezes ajuda os outros a entender é:
mylist[X:Y]
X é o índice do primeiro elemento que você deseja.
Y é o índice do primeiro elemento que você não deseja.
Index:
------------>
0 1 2 3 4
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
0 -4 -3 -2 -1
<------------
Slice:
<---------------|
|--------------->
: 1 2 3 4 :
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
: -4 -3 -2 -1 :
|--------------->
<---------------|
Espero que isso ajude você a modelar a lista em Python.
Referência: http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
Notação de fatia do Python:
a[start:end:step]
start
e end
, valores negativos são interpretados como sendo relativos ao final da sequência.end
indicam a posição após o último elemento a ser incluído.[+0:-0:1]
.start
eend
A notação se estende a matrizes (numpy) e matrizes multidimensionais. Por exemplo, para dividir colunas inteiras, você pode usar:
m[::,0:2:] ## slice the first two columns
As fatias contêm referências, não cópias, dos elementos da matriz. Se você deseja fazer uma cópia separada em uma matriz, pode usar deepcopy()
.
Isto é apenas para informações adicionais ... Considere a lista abaixo
>>> l=[12,23,345,456,67,7,945,467]
Alguns outros truques para reverter a lista:
>>> l[len(l):-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[len(l)::-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[::-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[-1:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
É assim que ensino fatias para iniciantes:
Entendendo a diferença entre indexação e fatia:
O Wiki Python tem essa imagem incrível que distingue claramente a indexação e o fatiamento.
É uma lista com seis elementos. Para entender melhor o fatiamento, considere essa lista como um conjunto de seis caixas juntas. Cada caixa tem um alfabeto.
A indexação é como lidar com o conteúdo da caixa. Você pode verificar o conteúdo de qualquer caixa. Mas você não pode verificar o conteúdo de várias caixas ao mesmo tempo. Você pode até substituir o conteúdo da caixa. Mas você não pode colocar duas bolas em uma caixa ou substituir duas por vez.
In [122]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [123]: alpha
Out[123]: ['a', 'b', 'c', 'd', 'e', 'f']
In [124]: alpha[0]
Out[124]: 'a'
In [127]: alpha[0] = 'A'
In [128]: alpha
Out[128]: ['A', 'b', 'c', 'd', 'e', 'f']
In [129]: alpha[0,1]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-129-c7eb16585371> in <module>()
----> 1 alpha[0,1]
TypeError: list indices must be integers, not tuple
Cortar é como lidar com as próprias caixas. Você pode pegar a primeira caixa e colocá-la em outra mesa. Para pegar a caixa, tudo o que você precisa saber é a posição de início e fim da caixa.
Você pode até pegar as três primeiras caixas ou as duas últimas caixas ou todas as caixas entre 1 e 4. Portanto, você pode escolher qualquer conjunto de caixas se souber o início e o final. Essas posições são chamadas de posições inicial e final.
O interessante é que você pode substituir várias caixas ao mesmo tempo. Além disso, você pode colocar várias caixas onde quiser.
In [130]: alpha[0:1]
Out[130]: ['A']
In [131]: alpha[0:1] = 'a'
In [132]: alpha
Out[132]: ['a', 'b', 'c', 'd', 'e', 'f']
In [133]: alpha[0:2] = ['A', 'B']
In [134]: alpha
Out[134]: ['A', 'B', 'c', 'd', 'e', 'f']
In [135]: alpha[2:2] = ['x', 'xx']
In [136]: alpha
Out[136]: ['A', 'B', 'x', 'xx', 'c', 'd', 'e', 'f']
Corte com etapa:
Até agora você selecionou caixas continuamente. Mas, às vezes, você precisa atender discretamente. Por exemplo, você pode escolher cada segunda caixa. Você pode até pegar todas as caixas do final. Este valor é chamado tamanho da etapa. Isso representa a lacuna entre seus captadores sucessivos. O tamanho da etapa deve ser positivo se você estiver escolhendo caixas do começo ao fim e vice-versa.
In [137]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [142]: alpha[1:5:2]
Out[142]: ['b', 'd']
In [143]: alpha[-1:-5:-2]
Out[143]: ['f', 'd']
In [144]: alpha[1:5:-2]
Out[144]: []
In [145]: alpha[-1:-5:2]
Out[145]: []
Como o Python descobre os parâmetros ausentes:
Ao fatiar, se você deixar de fora algum parâmetro, o Python tenta descobrir isso automaticamente.
Se você verificar o código fonte do CPython , encontrará uma função chamada PySlice_GetIndicesEx () que calcula os índices de uma fatia para qualquer parâmetro. Aqui está o código equivalente lógico no Python.
Essa função utiliza um objeto Python e parâmetros opcionais para fatiar e retorna o comprimento de início, parada, etapa e fatia da fatia solicitada.
def py_slice_get_indices_ex(obj, start=None, stop=None, step=None):
length = len(obj)
if step is None:
step = 1
if step == 0:
raise Exception("Step cannot be zero.")
if start is None:
start = 0 if step > 0 else length - 1
else:
if start < 0:
start += length
if start < 0:
start = 0 if step > 0 else -1
if start >= length:
start = length if step > 0 else length - 1
if stop is None:
stop = length if step > 0 else -1
else:
if stop < 0:
stop += length
if stop < 0:
stop = 0 if step > 0 else -1
if stop >= length:
stop = length if step > 0 else length - 1
if (step < 0 and stop >= start) or (step > 0 and start >= stop):
slice_length = 0
elif step < 0:
slice_length = (stop - start + 1)/(step) + 1
else:
slice_length = (stop - start - 1)/(step) + 1
return (start, stop, step, slice_length)
Essa é a inteligência que está presente atrás das fatias. Como o Python possui uma função interna chamada slice, você pode passar alguns parâmetros e verificar com que inteligência ele calcula os parâmetros ausentes.
In [21]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [22]: s = slice(None, None, None)
In [23]: s
Out[23]: slice(None, None, None)
In [24]: s.indices(len(alpha))
Out[24]: (0, 6, 1)
In [25]: range(*s.indices(len(alpha)))
Out[25]: [0, 1, 2, 3, 4, 5]
In [26]: s = slice(None, None, -1)
In [27]: range(*s.indices(len(alpha)))
Out[27]: [5, 4, 3, 2, 1, 0]
In [28]: s = slice(None, 3, -1)
In [29]: range(*s.indices(len(alpha)))
Out[29]: [5, 4]
Nota: Esta postagem foi originalmente escrita no meu blog The Intelligence Behind Python Slices .
Como regra geral, escrever código com muitos valores de índice codificados leva a uma bagunça de legibilidade e manutenção. Por exemplo, se você voltar ao código um ano depois, você o examinará e se perguntará o que estava pensando quando o escreveu. A solução mostrada é simplesmente uma maneira de indicar mais claramente o que seu código está realmente fazendo. Em geral, a fatia interna () cria um objeto de fatia que pode ser usado em qualquer lugar em que uma fatia seja permitida. Por exemplo:
>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4)
>>> items[2:4]
[2, 3]
>>> items[a]
[2, 3]
>>> items[a] = [10,11]
>>> items
[0, 1, 10, 11, 4, 5, 6]
>>> del items[a]
>>> items
[0, 1, 4, 5, 6]
Se você tiver uma instância de fatia s, poderá obter mais informações sobre ela olhando para os atributos s.start, s.stop e s.step, respectivamente. Por exemplo:
>>> a = slice(10, 50, 2) >>> a.start 10 >>> a.stop 50 >>> a.step 2 >>>
Para simplificar, lembre-se de que a fatia possui apenas uma forma:
s[start:end:step]
e aqui está como isso funciona:
s
: um objeto que pode ser cortadostart
: primeiro índice para iniciar a iteraçãoend
: último índice, NOTE que esse end
índice não será incluído na fatia resultantestep
: escolher elemento a cada step
índiceOutra coisa importação: tudo start
, end
, step
pode ser omitido! E se eles forem omitidas, seu valor padrão será utilizado: 0
, len(s)
, 1
em conformidade.
As variações possíveis são:
# Mostly used variations
s[start:end]
s[start:]
s[:end]
# Step-related variations
s[:end:step]
s[start::step]
s[::step]
# Make a copy
s[:]
NOTA: Se start >= end
(considerando apenas quando step>0
), o Python retornará uma fatia vazia []
.
A parte acima explica os principais recursos sobre como a fatia funciona e funcionará na maioria das ocasiões. No entanto, pode haver armadilhas que você deve prestar atenção, e esta parte as explica.
A primeira coisa que confunde os alunos de Python é que um índice pode ser negativo! Não entre em pânico: um índice negativo significa contar para trás.
Por exemplo:
s[-5:] # Start at the 5th index from the end of array,
# thus returning the last 5 elements.
s[:-5] # Start at index 0, and end until the 5th index from end of array,
# thus returning s[0:len(s)-5].
Tornar as coisas mais confusas é que também step
pode ser negativo!
Um passo negativo significa iterar a matriz para trás: do final ao início, com o índice final incluído e o índice inicial excluído do resultado.
NOTA : quando a etapa é negativa, o valor padrão para start
é len(s)
(while end
não é igual a 0
, porque s[::-1]
contém s[0]
). Por exemplo:
s[::-1] # Reversed slice
s[len(s)::-1] # The same as above, reversed slice
s[0:len(s):-1] # Empty list
Surpreenda-se: a fatia não gera um IndexError quando o índice está fora da faixa!
Se o índice estiver fora do intervalo, o Python fará o possível para definir o índice para 0
ou de len(s)
acordo com a situação. Por exemplo:
s[:len(s)+5] # The same as s[:len(s)]
s[-len(s)-5::] # The same as s[0:]
s[len(s)+5::-1] # The same as s[len(s)::-1], and the same as s[::-1]
Vamos terminar esta resposta com exemplos, explicando tudo o que discutimos:
# Create our array for demonstration
In [1]: s = [i for i in range(10)]
In [2]: s
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]: s[2:] # From index 2 to last index
Out[3]: [2, 3, 4, 5, 6, 7, 8, 9]
In [4]: s[:8] # From index 0 up to index 8
Out[4]: [0, 1, 2, 3, 4, 5, 6, 7]
In [5]: s[4:7] # From index 4 (included) up to index 7(excluded)
Out[5]: [4, 5, 6]
In [6]: s[:-2] # Up to second last index (negative index)
Out[6]: [0, 1, 2, 3, 4, 5, 6, 7]
In [7]: s[-2:] # From second last index (negative index)
Out[7]: [8, 9]
In [8]: s[::-1] # From last to first in reverse order (negative step)
Out[8]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
In [9]: s[::-2] # All odd numbers in reversed order
Out[9]: [9, 7, 5, 3, 1]
In [11]: s[-2::-2] # All even numbers in reversed order
Out[11]: [8, 6, 4, 2, 0]
In [12]: s[3:15] # End is out of range, and Python will set it to len(s).
Out[12]: [3, 4, 5, 6, 7, 8, 9]
In [14]: s[5:1] # Start > end; return empty list
Out[14]: []
In [15]: s[11] # Access index 11 (greater than len(s)) will raise an IndexError
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-15-79ffc22473a3> in <module>()
----> 1 s[11]
IndexError: list index out of range
As respostas anteriores não discutem o faturamento multidimensional de matrizes, o que é possível usando o famoso pacote NumPy :
O fatiamento também pode ser aplicado a matrizes multidimensionais.
# Here, a is a NumPy array
>>> a
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
>>> a[:2, 0:3:2]
array([[1, 3],
[5, 7]])
O " :2
" antes da vírgula opera na primeira dimensão e o " 0:3:2
" depois da vírgula opera na segunda dimensão.
list
, mas apenas em array
em Numpy
#!/usr/bin/env python
def slicegraphical(s, lista):
if len(s) > 9:
print """Enter a string of maximum 9 characters,
so the printig would looki nice"""
return 0;
# print " ",
print ' '+'+---' * len(s) +'+'
print ' ',
for letter in s:
print '| {}'.format(letter),
print '|'
print " ",; print '+---' * len(s) +'+'
print " ",
for letter in range(len(s) +1):
print '{} '.format(letter),
print ""
for letter in range(-1*(len(s)), 0):
print ' {}'.format(letter),
print ''
print ''
for triada in lista:
if len(triada) == 3:
if triada[0]==None and triada[1] == None and triada[2] == None:
# 000
print s+'[ : : ]' +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] == None and triada[1] == None and triada[2] != None:
# 001
print s+'[ : :{0:2d} ]'.format(triada[2], '','') +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] == None and triada[1] != None and triada[2] == None:
# 010
print s+'[ :{0:2d} : ]'.format(triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] == None and triada[1] != None and triada[2] != None:
# 011
print s+'[ :{0:2d} :{1:2d} ]'.format(triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] == None and triada[2] == None:
# 100
print s+'[{0:2d} : : ]'.format(triada[0]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] == None and triada[2] != None:
# 101
print s+'[{0:2d} : :{1:2d} ]'.format(triada[0], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] != None and triada[2] == None:
# 110
print s+'[{0:2d} :{1:2d} : ]'.format(triada[0], triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] != None and triada[2] != None:
# 111
print s+'[{0:2d} :{1:2d} :{2:2d} ]'.format(triada[0], triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif len(triada) == 2:
if triada[0] == None and triada[1] == None:
# 00
print s+'[ : ] ' + ' = ', s[triada[0]:triada[1]]
elif triada[0] == None and triada[1] != None:
# 01
print s+'[ :{0:2d} ] '.format(triada[1]) + ' = ', s[triada[0]:triada[1]]
elif triada[0] != None and triada[1] == None:
# 10
print s+'[{0:2d} : ] '.format(triada[0]) + ' = ', s[triada[0]:triada[1]]
elif triada[0] != None and triada[1] != None:
# 11
print s+'[{0:2d} :{1:2d} ] '.format(triada[0],triada[1]) + ' = ', s[triada[0]:triada[1]]
elif len(triada) == 1:
print s+'[{0:2d} ] '.format(triada[0]) + ' = ', s[triada[0]]
if __name__ == '__main__':
# Change "s" to what ever string you like, make it 9 characters for
# better representation.
s = 'COMPUTERS'
# add to this list different lists to experement with indexes
# to represent ex. s[::], use s[None, None,None], otherwise you get an error
# for s[2:] use s[2:None]
lista = [[4,7],[2,5,2],[-5,1,-1],[4],[-4,-6,-1], [2,-3,1],[2,-3,-1], [None,None,-1],[-5,None],[-5,0,-1],[-5,None,-1],[-1,1,-2]]
slicegraphical(s, lista)
Você pode executar esse script e experimentá-lo. Abaixo estão alguns exemplos que eu obtive do script.
+---+---+---+---+---+---+---+---+---+
| C | O | M | P | U | T | E | R | S |
+---+---+---+---+---+---+---+---+---+
0 1 2 3 4 5 6 7 8 9
-9 -8 -7 -6 -5 -4 -3 -2 -1
COMPUTERS[ 4 : 7 ] = UTE
COMPUTERS[ 2 : 5 : 2 ] = MU
COMPUTERS[-5 : 1 :-1 ] = UPM
COMPUTERS[ 4 ] = U
COMPUTERS[-4 :-6 :-1 ] = TU
COMPUTERS[ 2 :-3 : 1 ] = MPUT
COMPUTERS[ 2 :-3 :-1 ] =
COMPUTERS[ : :-1 ] = SRETUPMOC
COMPUTERS[-5 : ] = UTERS
COMPUTERS[-5 : 0 :-1 ] = UPMO
COMPUTERS[-5 : :-1 ] = UPMOC
COMPUTERS[-1 : 1 :-2 ] = SEUM
[Finished in 0.9s]
Ao usar uma etapa negativa, observe que a resposta é deslocada para a direita por 1.
Meu cérebro parece feliz em aceitar que lst[start:end]
contém o start
quinto item. Eu poderia até dizer que é uma "suposição natural".
Mas, ocasionalmente, surge uma dúvida e meu cérebro pede garantias de que não contém o end
-ésimo elemento.
Nestes momentos, confio neste teorema simples:
for any n, lst = lst[:n] + lst[n:]
Esta propriedade muito me diz que lst[start:end]
não contém o end
item de -ésimo porque ele está em lst[end:]
.
Observe que esse teorema é verdadeiro para qualquer n
um. Por exemplo, você pode verificar se
lst = range(10)
lst[:-42] + lst[-42:] == lst
retorna True
.
Na minha opinião, você entenderá e memorizará melhor a notação de fatiamento de strings do Python se a observar da seguinte maneira (continue lendo).
Vamos trabalhar com a seguinte string ...
azString = "abcdefghijklmnopqrstuvwxyz"
Para quem não sabe, você pode criar qualquer substring azString
usando a notaçãoazString[x:y]
Vindo de outras linguagens de programação, é aí que o senso comum fica comprometido. O que são x e y?
Tive que me sentar e executar vários cenários em minha busca por uma técnica de memorização que me ajudasse a lembrar o que xey eram e me ajudasse a cortar as cordas corretamente na primeira tentativa.
Minha conclusão é que xey devem ser vistos como os índices de contorno que cercam as strings que queremos extrair. Portanto, devemos ver a expressão como azString[index1, index2]
ou ainda mais clara como azString[index_of_first_character, index_after_the_last_character]
.
Aqui está um exemplo de visualização disso ...
Letters a b c d e f g h i j ...
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
┊ ┊
Indexes 0 1 2 3 4 5 6 7 8 9 ...
┊ ┊
cdefgh index1 index2
Portanto, tudo o que você precisa fazer é definir index1 e index2 com os valores que cercam a substring desejada. Por exemplo, para obter a subcadeia "cdefgh", você pode usarazString[2:8]
, porque o índice no lado esquerdo de "c" é 2 e o índice no tamanho certo de "h" é 8.
Lembre-se de que estamos estabelecendo limites. E esses limites são as posições em que você pode colocar alguns colchetes que serão enrolados ao redor da substring assim ...
ab [ cdefgh ] ij
Esse truque funciona o tempo todo e é fácil de memorizar.
A maioria das respostas anteriores esclarece perguntas sobre a notação de fatia.
A sintaxe de indexação estendida usada para fatiar é aList[start:stop:step]
e exemplos básicos são:
Mais exemplos de fatias : 15 fatias estendidas
No Python, a forma mais básica de fatiar é a seguinte:
l[start:end]
onde l
está uma coleção, start
é um índice inclusivo e end
é um índice exclusivo.
In [1]: l = list(range(10))
In [2]: l[:5] # First five elements
Out[2]: [0, 1, 2, 3, 4]
In [3]: l[-5:] # Last five elements
Out[3]: [5, 6, 7, 8, 9]
Ao fatiar desde o início, você pode omitir o índice zero e, ao fatiar até o final, pode omitir o índice final, pois é redundante, portanto, não seja detalhado:
In [5]: l[:3] == l[0:3]
Out[5]: True
In [6]: l[7:] == l[7:len(l)]
Out[6]: True
Inteiros negativos são úteis ao fazer compensações em relação ao final de uma coleção:
In [7]: l[:-1] # Include all elements but the last one
Out[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8]
In [8]: l[-3:] # Take the last three elements
Out[8]: [7, 8, 9]
É possível fornecer índices que estão fora dos limites ao fatiar, como:
In [9]: l[:20] # 20 is out of index bounds, and l[20] will raise an IndexError exception
Out[9]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [11]: l[-20:] # -20 is out of index bounds, and l[-20] will raise an IndexError exception
Out[11]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Lembre-se de que o resultado do fatiamento de uma coleção é uma coleção totalmente nova. Além disso, ao usar a notação de fatia em atribuições, o comprimento das atribuições de fatia não precisa ser o mesmo. Os valores antes e depois da fatia atribuída serão mantidos e a coleção será reduzida ou aumentada para conter os novos valores:
In [16]: l[2:6] = list('abc') # Assigning fewer elements than the ones contained in the sliced collection l[2:6]
In [17]: l
Out[17]: [0, 1, 'a', 'b', 'c', 6, 7, 8, 9]
In [18]: l[2:5] = list('hello') # Assigning more elements than the ones contained in the sliced collection l [2:5]
In [19]: l
Out[19]: [0, 1, 'h', 'e', 'l', 'l', 'o', 6, 7, 8, 9]
Se você omitir o índice inicial e final, você fará uma cópia da coleção:
In [14]: l_copy = l[:]
In [15]: l == l_copy and l is not l_copy
Out[15]: True
Se os índices inicial e final forem omitidos ao executar uma operação de atribuição, todo o conteúdo da coleção será substituído por uma cópia do que é referenciado:
In [20]: l[:] = list('hello...')
In [21]: l
Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.']
Além do fatiamento básico, também é possível aplicar a seguinte notação:
l[start:end:step]
where l
é uma coleção, start
é um índice inclusivo, end
é um índice exclusivo e step
é um passo que pode ser usado para incluir cada enésimo item l
.
In [22]: l = list(range(10))
In [23]: l[::2] # Take the elements which indexes are even
Out[23]: [0, 2, 4, 6, 8]
In [24]: l[1::2] # Take the elements which indexes are odd
Out[24]: [1, 3, 5, 7, 9]
Usar step
fornece um truque útil para reverter uma coleção em Python:
In [25]: l[::-1]
Out[25]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Também é possível usar números inteiros negativos para step
o seguinte exemplo:
In[28]: l[::-2]
Out[28]: [9, 7, 5, 3, 1]
No entanto, usar um valor negativo para step
pode se tornar muito confuso. Além disso, a fim de ser Pythonic , você deve evitar usar start
, end
e step
em uma única fatia. Caso isso seja necessário, considere fazer isso em duas tarefas (uma para cortar e outra para caminhar).
In [29]: l = l[::2] # This step is for striding
In [30]: l
Out[30]: [0, 2, 4, 6, 8]
In [31]: l = l[1:-1] # This step is for slicing
In [32]: l
Out[32]: [2, 4, 6]
Quero adicionar um Olá, mundo! exemplo que explica o básico de fatias para os iniciantes. Isto me ajudou bastante.
Vamos ter uma lista com seis valores ['P', 'Y', 'T', 'H', 'O', 'N']
:
+---+---+---+---+---+---+
| P | Y | T | H | O | N |
+---+---+---+---+---+---+
0 1 2 3 4 5
Agora, as fatias mais simples dessa lista são suas sublistas. A notação é [<index>:<index>]
e a chave é lê-la assim:
[ start cutting before this index : end cutting before this index ]
Agora, se você fizer uma fatia [2:5]
da lista acima, isso acontecerá:
| |
+---+---|---+---+---|---+
| P | Y | T | H | O | N |
+---+---|---+---+---|---+
0 1 | 2 3 4 | 5
Você fez um corte antes do elemento com índice 2
e outro corte antes do elemento com índice 5
. Portanto, o resultado será uma fatia entre esses dois cortes, uma lista ['T', 'H', 'O']
.
A seguir, o exemplo de um índice de uma string:
+---+---+---+---+---+
| H | e | l | p | A |
+---+---+---+---+---+
0 1 2 3 4 5
-5 -4 -3 -2 -1
str="Name string"
Exemplo de fatia: [start: end: step]
str[start:end] # Items start through end-1
str[start:] # Items start through the rest of the array
str[:end] # Items from the beginning through end-1
str[:] # A copy of the whole array
Abaixo está o exemplo de uso:
print str[0] = N
print str[0:2] = Na
print str[0:7] = Name st
print str[0:7:2] = Nm t
print str[0:-1:2] = Nm ti
Se você acha que os índices negativos no fatiamento são confusos, aqui está uma maneira muito fácil de pensar sobre isso: basta substituir o índice negativo por len - index
. Por exemplo, substitua -3 por len(list) - 3
.
A melhor maneira de ilustrar o que o fatiamento faz internamente é apenas mostrá-lo no código que implementa esta operação:
def slice(list, start = None, end = None, step = 1):
# Take care of missing start/end parameters
start = 0 if start is None else start
end = len(list) if end is None else end
# Take care of negative start/end parameters
start = len(list) + start if start < 0 else start
end = len(list) + end if end < 0 else end
# Now just execute a for-loop with start, end and step
return [list[i] for i in range(start, end, step)]
A técnica básica de fatiar é definir o ponto de partida, o ponto de parada e o tamanho do passo - também conhecido como passada.
Primeiro, criaremos uma lista de valores para usar em nosso fatiamento.
Crie duas listas para fatiar. A primeira é uma lista numérica de 1 a 9 (Lista A). O segundo também é uma lista numérica, de 0 a 9 (Lista B):
A = list(range(1, 10, 1)) # Start, stop, and step
B = list(range(9))
print("This is List A:", A)
print("This is List B:", B)
Indexe o número 3 de A e o número 6 de B.
print(A[2])
print(B[6])
Fatiamento básico
A sintaxe de indexação estendida usada para fatiar é aList [start: stop: step]. O argumento inicial e o argumento da etapa assumem como padrão nenhum - o único argumento necessário é parar. Você percebeu que isso é semelhante ao modo como o intervalo foi usado para definir as listas A e B? Isso ocorre porque o objeto de fatia representa o conjunto de índices especificados pelo intervalo (iniciar, parar, etapa). Documentação do Python 3.4.
Como você pode ver, definir apenas stop retorna um elemento. Como o início não é padrão, isso significa recuperar apenas um elemento.
É importante notar que o primeiro elemento é o índice 0, não índice 1. É por isso que estamos usando 2 listas para este exercício. Os elementos da lista A são numerados de acordo com a posição ordinal (o primeiro elemento é 1, o segundo elemento é 2 etc.) enquanto os elementos da lista B são os números que seriam usados para indexá-los ([0] para o primeiro elemento 0, etc.)
Com a sintaxe de indexação estendida, recuperamos um intervalo de valores. Por exemplo, todos os valores são recuperados com dois pontos.
A[:]
Para recuperar um subconjunto de elementos, as posições de início e parada precisam ser definidas.
Dado o padrão aList [start: stop], recupere os dois primeiros elementos da Lista A.
Eu não acho que o diagrama tutorial do Python (citado em várias outras respostas) seja bom, pois essa sugestão funciona com passos positivos, mas não com passos negativos.
Este é o diagrama:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
Do diagrama, espero a[-4,-6,-1]
ser, yP
mas é ty
.
>>> a = "Python"
>>> a[2:4:1] # as expected
'th'
>>> a[-4:-6:-1] # off by 1
'ty'
O que sempre funciona é pensar em caracteres ou slots e usar a indexação como um intervalo semiaberto - abertura à direita se for positivo, abertura à esquerda se for um passo negativo.
Dessa forma, eu posso pensar a[-4:-6:-1]
como a(-6,-4]
na terminologia de intervalo.
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
+---+---+---+---+---+---+---+---+---+---+---+---+
| P | y | t | h | o | n | P | y | t | h | o | n |
+---+---+---+---+---+---+---+---+---+---+---+---+
-6 -5 -4 -3 -2 -1 0 1 2 3 4 5