Como outros mencionados, pop e del são as maneiras eficientes de remover um item de um determinado índice. No entanto, apenas para fins de conclusão (já que a mesma coisa pode ser feita de várias maneiras no Python):
Usando fatias (isso não remove o item da lista original):
(Além disso, este será o método menos eficiente ao trabalhar com a lista Python, mas isso pode ser útil (mas não eficiente, reitero) ao trabalhar com objetos definidos pelo usuário que não suportam pop, mas definem a __getitem__
):
>>> a = [1, 2, 3, 4, 5, 6]
>>> index = 3 # Only positive index
>>> a = a[:index] + a[index+1 :]
# a is now [1, 2, 3, 5, 6]
Nota: Observe que este método não modifica a lista no local como pop
e del
. Em vez disso, ele faz duas cópias das listas (uma desde o início até o índice, mas sem ela ( a[:index]
) e uma após o índice até o último elemento ( a[index+1:]
)) e cria um novo objeto de lista adicionando ambas. Isso é reatribuído à variável da lista ( a
). Portanto, o objeto de lista antigo é desreferenciado e, portanto, coletado de lixo (desde que o objeto de lista original não seja referenciado por nenhuma variável que não seja a).
Isso torna esse método muito ineficiente e também pode produzir efeitos colaterais indesejáveis (especialmente quando outras variáveis apontam para o objeto de lista original que permanece inalterado).
Obrigado a @MarkDickinson por apontar isso ...
Esta resposta de estouro de pilha explica o conceito de fatiar.
Observe também que isso funciona apenas com índices positivos.
Ao usar com objetos, o __getitem__
método deve ter sido definido e, mais importante, o __add__
método deve ter sido definido para retornar um objeto contendo itens de ambos os operandos.
Em essência, isso funciona com qualquer objeto cuja definição de classe seja como:
class foo(object):
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return foo(self.items[index])
def __add__(self, right):
return foo( self.items + right.items )
Isso funciona com o list
qual define __getitem__
e __add__
métodos.
Comparação das três formas em termos de eficiência:
Suponha que o seguinte seja predefinido:
a = range(10)
index = 3
O del object[index]
método:
De longe, o método mais eficiente. Funciona com todos os objetos que definem um __del__
método.
A desmontagem é a seguinte:
Código:
def del_method():
global a
global index
del a[index]
Desmontagem:
10 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (index)
6 DELETE_SUBSCR # This is the line that deletes the item
7 LOAD_CONST 0 (None)
10 RETURN_VALUE
None
pop
método:
É menos eficiente que o método del e é usado quando você precisa obter o item excluído.
Código:
def pop_method():
global a
global index
a.pop(index)
Desmontagem:
17 0 LOAD_GLOBAL 0 (a)
3 LOAD_ATTR 1 (pop)
6 LOAD_GLOBAL 2 (index)
9 CALL_FUNCTION 1
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
A fatia e o método add.
O menos eficiente.
Código:
def slice_method():
global a
global index
a = a[:index] + a[index+1:]
Desmontagem:
24 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (index)
6 SLICE+2
7 LOAD_GLOBAL 0 (a)
10 LOAD_GLOBAL 1 (index)
13 LOAD_CONST 1 (1)
16 BINARY_ADD
17 SLICE+1
18 BINARY_ADD
19 STORE_GLOBAL 0 (a)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
None
Nota: Nas três desmontagens, ignore as duas últimas linhas que basicamente são return None
. Além disso, as duas primeiras linhas estão carregando os valores globais a
e index
.
O(n)
em operação no tempo.deque()
fornece operações eficientes em ambas as extremidades, mas não fornece O (1) inserções / pesquisas / exclusões no meio.