Answer is somewhat outdated and lacks some additional details. I fixed what was most grotesque and the night I will rewrite it.
You can filter your list of 3 possible ways:
- Using the function
filter
- Using list comprehensions
- Using generators
Function filter
In advance of the answer, you can take advantage of the tools that language gives you. How do you want to make a filter on the values of a list, nothing better than using the function filter
python:
>>> lista = [2, 3, 1, 5, 1, 7, 8, 8, 9, 15, 1, 1]
>>> lista = list(filter(lambda x: x != 1, lista))
>>> print(lista)
[2, 3, 5, 7, 8, 8, 9, 15]
Returns an eternal object containing the values of the second parameter whose execution of function
on the same return True
.
iterable filter(function, iterable)
That is, by doing:
filter(myFilter, lista)
Will be returned all values a generator of lista
in which myFilter(x)
, being x
the element of lista
, true return. As you want to filter the values equal to 1, just have the condition: x != 1
. The function was used lambda
due to the simplicity of the function, but nothing stops doing:
>>> lista = [2, 3, 1, 5, 1, 7, 8, 8, 9, 15, 1, 1]
>>> def is_not_one (value):
... return value != 1
>>> lista = list(filter(is_not_one, lista))
>>> print(lista)
[2, 3, 5, 7, 8, 8, 9, 15]
The result is exactly the same.
When to use?
The function filter
is ideal to be used when filter logic is not so trivial (you can’t write in a line of code).
Basic test:
import random, time, sys
SIZE = 1000000
# Gera-se dados aleatórios entre 0 e 1
lista = [random.randrange(0, 9) for _ in range(SIZE)]
# Filtra a lista através de compressão de listas
START_TIME = time.time()
# Filtra a listra através da função `filter`
list_filter = filter(lambda i: i != 1, lista)
FILTER_TIME = time.time()
print("Execução em: ", FILTER_TIME - START_TIME)
print("Consumo em memória: ", sys.getsizeof(list_filter))
Exit:
Execução em: 5.9604644775390625e-06
Consumo em memória: 56
List Comprehensions
Like answered by the user Camilo Santos:
>>> lista = [2, 3, 1, 5, 1, 7, 8, 8, 9, 15, 1, 1]
>>> lista = [l for l in lista if l != 1]
>>> print(lista)
[2, 3, 5, 7, 8, 8, 9, 15]
When to use?
It is ideal to use the list comprehensions when the number of elements in the list is small and the filter logic is trivial (which can be written in a row). The new list will be stored completely in memory and, with this, can consume a lot of machine resource if it is too extensive.
Basic test:
import random, time, sys
SIZE = 1000000
# Gera-se dados aleatórios entre 0 e 1
lista = [random.randrange(0, 9) for _ in range(SIZE)]
# Filtra a lista através de compressão de listas
START_TIME = time.time()
list_comprehension = [i for i in lista if i != 1]
LIST_TIME = time.time()
print("Execução em: ", LIST_TIME - START_TIME)
print("Consumo em memória: ", sys.getsizeof(list_comprehension))
Exit:
Execução em: 0.05048513412475586
Consumo em memória: 7731040
Consumes memory and running time, so should be used with caution.
Generator
Using the Python generator tool:
>>> def filter_by_generator(lista, value):
... for i in lista:
... if i != value: yield i
>>> lista = filter_by_generator(lista, 1)
>>> print(list(lista))
[2, 3, 5, 7, 8, 8, 9, 15]
When to use?
The generators should be used when the number of items on the list is too large, regardless of how complex the filter logic is (if simple, you can use filter
and reduce the code).
Basic test:
import random, time, sys
SIZE = 1000000
# Gera-se dados aleatórios entre 0 e 1
lista = [random.randrange(0, 9) for _ in range(SIZE)]
START_TIME = time.time()
# Filtra a lista através de gerador
def filter_by_generator(lista, value):
for i in lista:
if i != value: yield i
lista_generator = filter_by_generator(lista, 1)
GENERATOR_TIME = time.time()
print("Execução em: ", GENERATOR_TIME - START_TIME)
print("Consumo em memória: ", sys.getsizeof(lista_generator))
Exit:
Execução em: 4.291534423828125e-06
Consumo em memória: 88
Both runtime and memory space are much shorter than other methods. This is because the Generator does not compute the entire list at once, but generates each list item in "real time" when it is iterated.
Why do
qtd = qtd - 1
? What logic did you imagine?– Woss
Because the size of the list was being immutable. For example the list has 11 elements and the "for" would always be 11, but when you entered the if was to decrease the size and update the "for". Because when you enter if you remove an element
– Jose.Lemo
Exactly. That’s why you can’t do it the way you tried to do it. You can’t iterate on the object being changed inside the
for
. It can be done by copying the object and iterating over the copy, but the options I mentioned in the answer are much more elegant.– Woss