É possível excluir vários elementos de uma lista ao mesmo tempo? Se eu quiser excluir elementos no índice 0 e 2 e tentar algo como del somelist[0]
, seguido por del somelist[2]
, a segunda instrução será realmente excluída somelist[3]
.
Suponho que sempre posso excluir os elementos com números mais altos primeiro, mas espero que exista uma maneira melhor.
somelist = [ lst[i] for i in xrange(len(lst)) if i not in set(indices) ]
:?Por alguma razão, não gosto de nenhuma das respostas aqui. Sim, eles funcionam, mas, estritamente falando, a maioria deles não está excluindo elementos de uma lista, pois não? (Mas faça uma cópia e substitua a original pela cópia editada).
Por que não excluir o índice mais alto primeiro?
Existe uma razão para isso? Eu apenas faria:
Se você realmente não deseja excluir itens de trás para frente, acho que você deve apenas incrementar os valores dos índices maiores que o último índice excluído (não é possível usar o mesmo índice porque você está com uma lista diferente) ou usar uma cópia da lista (que não seria 'excluída', mas substituindo o original por uma cópia editada).
Estou faltando alguma coisa aqui, algum motivo para NÃO excluir na ordem inversa?
fonte
Se você estiver excluindo vários itens não adjacentes, o que você descreve é a melhor maneira (e sim, certifique-se de começar do índice mais alto).
Se seus itens forem adjacentes, você poderá usar a sintaxe de atribuição de fatia:
fonte
del a[2:10]
com o mesmo efeito.Você pode usar da
numpy.delete
seguinte maneira:Se você não se importa em terminar com uma
numpy
matriz no final, pode deixar de fora o.tolist()
. Você também verá algumas melhorias importantes na velocidade, tornando a solução mais escalável. Eu não o comparei, mas asnumpy
operações são código compilado escrito em C ou Fortran.fonte
Como especialização da resposta de Greg, você pode até usar a sintaxe de fatia estendida. por exemplo. Se você deseja excluir os itens 0 e 2:
Isso não cobre nenhuma seleção arbitrária, é claro, mas certamente pode funcionar para excluir dois itens.
fonte
Como uma função:
Executa no tempo n log (n) , o que deve torná-lo a solução correta mais rápida até o momento.
fonte
n log n
? Realmente? Eu não acho quedel list[index]
é O (1).Então, você deseja excluir vários elementos de uma só vez? Nesse caso, a posição do próximo elemento a ser excluído será deslocada por muitos que foram excluídos anteriormente.
Nosso objetivo é excluir todas as vogais, que são pré-computadas como índices 1, 4 e 7. Observe que é importante que os índices to_delete estejam em ordem crescente, caso contrário, não funcionará.
Seria mais complicado se você quisesse excluir os elementos em qualquer ordem. Na IMO, a classificação
to_delete
pode ser mais fácil do que descobrir quando você deve ou não subtrairindex
.fonte
Sou iniciante em Python e minha programação no momento é grosseira e suja, para dizer o mínimo, mas minha solução foi usar uma combinação dos comandos básicos que aprendi nos primeiros tutoriais:
Obviamente, por ter que escolher um caractere "marca para exclusão", isso tem suas limitações.
Quanto ao desempenho conforme o tamanho da lista, tenho certeza de que minha solução está abaixo do ideal. No entanto, é simples, o que espero atrair outros iniciantes, e funcionará em casos simples, onde
some_list
é de um formato conhecido, por exemplo, sempre numérico ...fonte
Aqui está uma alternativa, que não usa enumerate () para criar tuplas (como na resposta original do SilentGhost).
Isso me parece mais legível. (Talvez eu me sentisse diferente se tivesse o hábito de usar enumerar.) CAVEAT: Não testei o desempenho das duas abordagens.
NOTA: Sintaxe do Python 2.7. Para Python 3,
xrange
=>range
.Uso:
lista de som:
--- BÔNUS ---
Exclua vários valores de uma lista. Ou seja, temos os valores que queremos excluir:
Uso:
lista de som:
Esta é a mesma resposta de antes, mas desta vez fornecemos os VALORES a serem excluídos
[0, 44, 55]
.fonte
[ value for (i, value) in enumerate(lst) if i not in set(indices) ]
. Mas vou deixar minha resposta aqui, porque também mostro como excluir por valores. Qual é o caso mais fácil, mas pode ajudar alguém.indices_as_set = set(indices)
,[ value for (i, value) in enumerate(lst) if i not in indices_as_set ]
, para acelerá-lo.delete__by_values()
?Um método alternativo de compreensão de lista que usa valores de índice de lista:
Isso retorna:
fonte
index
é enganador, uma vez na lista de iterador é usado o métodoindex()
Aqui está outro método que remove os elementos no lugar. Além disso, se sua lista for realmente longa, será mais rápida.
fonte
Isso foi mencionado, mas de alguma forma ninguém conseguiu acertar.
Na
O(n)
solução seria:Isso está muito próximo da versão do SilentGhost , mas adiciona duas chaves.
fonte
O(n)
se você contar as pesquisas necessáriaslog(len(indices))
para cada iteração.j not in indices
éO(1)
.j not in indices
ainda é necessário procurar, o que éO(log(len(indices)))
. Embora eu concorde que uma pesquisa em um conjunto de 2 elementos se qualifique comoO(1)
, no caso geral, seráO(log(N))
. De qualquer maneiraO(N log(N))
ainda bateO(N^2)
.j not in indices
éO(1)
, sério.É basicamente o mesmo que a resposta mais votada, apenas uma maneira diferente de escrevê-la. Observe que usar l.index () não é uma boa ideia, porque não pode manipular elementos duplicados em uma lista.
fonte
O método Remove causa muitas mudanças nos elementos da lista. Eu acho que é melhor fazer uma cópia:
fonte
tecnicamente, a resposta é NÃO, não é possível excluir dois objetos AO MESMO TEMPO. No entanto, é possível excluir dois objetos em uma linha de belo python.
excluirá recusrively
foo['bar']
, entãofoo['baz']
fonte
podemos fazer isso usando um loop for iterando sobre os índices depois de classificar a lista de índices em ordem decrescente
fonte
Para os índices 0 e 2 da lista A:
Para remover alguns índices aleatórios da lista A:
fonte
Eu queria uma maneira de comparar as diferentes soluções que tornavam mais fácil girar os botões.
Primeiro eu gerei meus dados:
Então eu defini minhas funções:
Então eu costumava
timeit
comparar as soluções:Resultado
Então o gerador com os índices em a
set
foi o vencedor. Edel
é um pouco mais rápido entãopop
.fonte
Você pode usar esta lógica:
fonte
Outra implementação da idéia de remover do índice mais alto.
fonte
Eu posso pensar em duas maneiras de fazer isso:
divida a lista como (isso exclui o primeiro, o terceiro e o oitavo elementos)
lista somelist = lista somel [1: 2] + lista somel [3: 7] + lista somel [8:]
faça isso no lugar, mas um de cada vez:
somelist.pop (2) somelist.pop (0)
fonte
Você pode fazer isso em um ditado, não em uma lista. Em uma lista, os elementos estão em sequência. Em um ditado, eles dependem apenas do índice.
Código simples apenas para explicar, fazendo :
Uma maneira de "converter" uma lista em um ditado é:
O inverso é:
Enfim, acho melhor começar a excluir do índice mais alto, como você disse.
fonte
Para generalizar o comentário de @sth . A exclusão do item em qualquer classe que implemente o abc.MutableSequence e,
list
em particular, é feita por meio do__delitem__
método mágico. Esse método funciona de maneira semelhante a__getitem__
, o que significa que ele pode aceitar um número inteiro ou uma fatia. Aqui está um exemplo:Isso produzirá
fonte
Importá-lo apenas por esse motivo pode ser um exagero, mas se você o estiver usando de
pandas
qualquer maneira, a solução será simples e direta:fonte
Evita o custo de classificação e a necessidade de copiar explicitamente a lista.
fonte
Que tal um deles (eu sou muito novo no Python, mas eles parecem bem):
['Atlântico', 'Pacífico', 'Indiano']
['Atlântico', 'Pacífico', 'Indiano']
fonte
Nenhuma das respostas oferecidas até agora executa a exclusão em O (n) no comprimento da lista para um número arbitrário de índices a serem excluídos, então aqui está minha versão:
fonte
Você pode usar remover também.
fonte
Reuni tudo em uma
list_diff
função que simplesmente pega duas listas como entradas e retorna sua diferença, preservando a ordem original da primeira lista.Uso da amostra:
fonte