list.append()
é a escolha óbvia para adicionar ao final de uma lista. Aqui está uma explicação razoável para os desaparecidos list.prepend()
. Supondo que minha lista seja curta e as preocupações com o desempenho sejam insignificantes, é
list.insert(0, x)
ou
list[0:0] = [x]
idiomático?
Se você pode seguir o caminho funcional, o seguinte é bem claro
É claro que você não inseriu ,
x
emyour_list
vez disso, criou uma nova lista com ax
pré-prevista.fonte
Geralmente, você não deseja anexar repetidamente uma lista em Python.
Se for curto e você não estiver fazendo muito ... então tudo bem.
list.insert
O
list.insert
pode ser usado dessa maneira.Mas isso é ineficiente, porque, em Python, a
list
é uma matriz de ponteiros, e agora o Python deve pegar todos os ponteiros da lista e movê-lo para baixo em um para inserir o ponteiro no seu objeto no primeiro slot, portanto, isso é realmente apenas eficiente para listas bastante curtas, como você pede.Aqui está um trecho da fonte CPython onde isso é implementado - e como você pode ver, começamos no final da matriz e movemos tudo para baixo em um para cada inserção:
Se você deseja um contêiner / lista eficiente na adição de elementos, deseja uma lista vinculada. O Python tem uma lista duplamente vinculada, que pode ser inserida no início e no final rapidamente - é chamada de a
deque
.deque.appendleft
A
collections.deque
tem muitos dos métodos de uma lista.list.sort
é uma exceção, tornandodeque
definitivamente não inteiramente Liskov substituívellist
.O
deque
também possui umappendleft
método (assim comopopleft
). Odeque
é um deque e uma lista duplamente vinculada - não importa o comprimento, ele sempre leva a mesma quantidade de tempo para preprend algo. Na notação O grande, O (1) versus o tempo O (n) das listas. Aqui está o uso:deque.extendleft
Também relevante é o
extendleft
método de deque , que precede iterativamente:Observe que cada elemento será anexado um de cada vez, revertendo efetivamente sua ordem.
Desempenho de
list
versusdeque
Primeiro, configuramos com alguns anexos iterativos:
e desempenho:
O deque é muito mais rápido. À medida que as listas ficam mais longas, eu esperaria que um deque tivesse um desempenho ainda melhor. Se você pode usar o deque,
extendleft
provavelmente obterá o melhor desempenho dessa maneira.fonte
Se alguém encontrar essa pergunta como eu, aqui estão meus testes de desempenho dos métodos propostos:
Como você pode ver, a
insert
atribuição de fatias é quase duas vezes mais rápida que a adição explícita e os resultados são muito próximos. Como Raymond Hettinger notou,insert
é uma opção mais comum e eu, pessoalmente, prefiro essa maneira de acrescentar à lista.fonte
.insert
e[0:0] = [0]
trabalho no local , eles ainda têm de re-alocar o buffer inteiro.