fatia alargada que vai para o início da seqüência com passo negativo
Pergunta
Bear comigo enquanto eu explicar a minha pergunta. Vá até o título em negrito se você já entendeu estendida lista fatia de indexação.
Em Python, você pode listas de índice usando a notação de fatia. Aqui está um exemplo:
>>> A = list(range(10))
>>> A[0:5]
[0, 1, 2, 3, 4]
Você também pode incluir um passo, que atua como um "passo":
>>> A[0:5:2]
[0, 2, 4]
O passo também é permitido ser negativo, o que significa que os elementos são recuperados em ordem inversa:
>>> A[5:0:-1]
[5, 4, 3, 2, 1]
Mas espere! Eu queria ver [4, 3, 2, 1, 0]
. Oh, eu vejo, eu preciso diminuir os índices de início e término:
>>> A[4:-1:-1]
[]
O que aconteceu? É interpretar -1 como estando na extremidade da matriz, não o início. Eu sei que você pode conseguir isso da seguinte forma:
>>> A[4::-1]
[4, 3, 2, 1, 0]
Mas você não pode usar isso em todos os casos. Por exemplo, em um método que tem sido passada índices.
A minha pergunta é:
Existe alguma boa maneira Python de usar partições extendidas com passos negativos e início explícita e índices finais , que incluem o primeiro elemento de uma seqüência?
Isto é o que eu vim acima com até agora, mas parece insatisfatório.
>>> A[0:5][::-1]
[4, 3, 2, 1, 0]
Solução 2
Ok, eu acho que esta é provavelmente tão boa como eu vai buscá-la. Graças à Abgan para que provocou a idéia. Esta baseia-se no fato de que nenhum de uma fatia é tratado como se fosse um parâmetro em falta. Ninguém melhor coisa tem?
def getReversedList(aList, end, start, step):
return aList[end:start if start!=-1 else None:step]
edit: cheque de start==-1
, não 0
Este ainda não é o ideal, porque você está a esmagar o comportamento habitual de -1. Parece que o problema aqui é duas definições sobrepostas do que deveria acontecer. Quem ganhar leva embora invocações de outra forma válidos procurando a outra intenção.
Outras dicas
É para mudar a semântica da start
e stop
propenso a erros. Use None
ou -(len(a) + 1)
vez de 0
ou -1
. A semântica não é arbitrária. O artigo de Veja Edsger W. Dijkstra "Por numeração deve começar no zero" .
>>> a = range(10)
>>> start, stop, step = 4, None, -1
ou
>>> start, stop, step = 4, -(len(a) + 1), -1
>>> a[start:stop:step]
[4, 3, 2, 1, 0]
ou
>>> s = slice(start, stop, step)
>>> a[s]
[4, 3, 2, 1, 0]
Quando s
é uma sequência os índices negativos em s[i:j:k]
são especialmente tratada :
Se
i
ouj
é negativo, o índice é relativo ao final da string:len(s) + i
oulen(s) + j
é substituído. Mas nota que-0
ainda é0
.
por isso len(range(10)[4:-1:-1]) == 0
porque é equivalente a range(10)[4:9:-1]
.
[ A[b] for b in range(end,start,stride) ]
Mais lento, no entanto você pode usar índices negativos, então isso deve funcionar:
[ A[b] for b in range(9, -1, -1) ]
Sei que isso não está usando fatias, mas pensei que eu iria oferecer a solução de qualquer maneira se utilizando fatias especificamente para obter o resultado não é uma prioridade.
Eu acredito que o seguinte não satisfazê-lo:
def getReversedList(aList, end, start, step):
if step < 0 and start == 0:
return aList[end::step]
return aList[end:start:step]
ou não? : -)
Mas você não pode usar isso se você estiver armazenar seus índices em variáveis ??para exemplo.
É este satisfatória?
>>> a = range(10)
>>> start = 0
>>> end = 4
>>> a[4:start-1 if start > 0 else None:-1]
[4, 3, 2, 1, 0]
Como você diz muito poucas pessoas entender completamente tudo o que você pode fazer com corte prolongado, a menos que você realmente precisa do desempenho extra eu fizer isso da maneira "óbvia":
rev_subset = reversed(data[start:stop])
a[4::-1]
Exemplo:
Python 2.6 (r26:66714, Dec 4 2008, 11:34:15)
[GCC 4.0.1 (Apple Inc. build 5488)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[4:0:-1]
[4, 3, 2, 1]
>>> a[4::-1]
[4, 3, 2, 1, 0]
>>>
A razão é que o segundo termo é interpretado como "enquanto não índice ==". Deixando-o para fora é "enquanto o índice na faixa".
Eu sei que isto é uma questão antiga, mas no caso de alguém como eu, está à procura de respostas:
>>> A[5-1::-1]
[4, 3, 2, 1, 0]
>>> A[4:1:-1]
[4, 3, 2]
Você pode usar um objeto slice(start, stop, step)
, que é tal que
s=slice(start, stop, step)
print a[s]
é o mesmo que
print a[start : stop : step]
e, além disso, você pode definir qualquer um dos argumentos para None
para indicar nada entre os dois pontos. Assim, no caso que você dá, você pode usar slice(4, None, -1)
.