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]
Foi útil?

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 ou j é negativo, o índice é relativo ao final da string: len(s) + i ou len(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).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top