In Python zal remove()
het eerste voorkomen van waarde in een lijst verwijderen.
Hoe verwijder ik alleinstanties van een waarde uit een lijst?
Dit is wat ik in gedachten heb:
>>> remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
[1, 3, 4, 3]
Antwoord 1, autoriteit 100%
Functionele aanpak:
Python 3.x
>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter((2).__ne__, x))
[1, 3, 3, 4]
of
>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter(lambda a: a != 2, x))
[1, 3, 3, 4]
Python 2.x
>>> x = [1,2,3,2,2,2,3,4]
>>> filter(lambda a: a != 2, x)
[1, 3, 3, 4]
Antwoord 2, autoriteit 40%
U kunt een lijstbegrip gebruiken:
def remove_values_from_list(the_list, val):
return [value for value in the_list if value != val]
x = [1, 2, 3, 4, 2, 2, 3]
x = remove_values_from_list(x, 2)
print x
# [1, 3, 4, 3]
Antwoord 3, autoriteit 21%
U kunt slice-toewijzing gebruiken als de originele lijst moet worden gewijzigd, terwijl u toch een efficiënt lijstbegrip (of generatorexpressie) gebruikt.
>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> x[:] = (value for value in x if value != 2)
>>> x
[1, 3, 4, 3]
Antwoord 4, autoriteit 7%
De oplossing van de eerste post op een meer abstracte manier herhalen:
>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> while 2 in x: x.remove(2)
>>> x
[1, 3, 4, 3]
Antwoord 5, autoriteit 6%
Zie de eenvoudige oplossing
>>> [i for i in x if i != 2]
Hiermee wordt een lijst geretourneerd met alle elementen van x
zonder 2
Antwoord 6, autoriteit 2%
Alle antwoorden hierboven (behalve die van Martin Andersson) creëren een nieuwe lijst zonder de gewenste items, in plaats van de items uit de originele lijst te verwijderen.
>>> import random, timeit
>>> a = list(range(5)) * 1000
>>> random.shuffle(a)
>>> b = a
>>> print(b is a)
True
>>> b = [x for x in b if x != 0]
>>> print(b is a)
False
>>> b.count(0)
0
>>> a.count(0)
1000
>>> b = a
>>> b = filter(lambda a: a != 2, x)
>>> print(b is a)
False
Dit kan belangrijk zijn als je andere verwijzingen naar de lijst hebt hangen.
Gebruik een methode als deze om de bestaande lijst aan te passen
>>> def removeall_inplace(x, l):
... for _ in xrange(l.count(x)):
... l.remove(x)
...
>>> removeall_inplace(0, b)
>>> b is a
True
>>> a.count(0)
0
Wat snelheid betreft, zijn de resultaten op mijn laptop (allemaal op een 5000 deelnemerslijst met 1000 verwijderde inzendingen)
- Lijst begrip – ~400us
- Filteren – ~900us
- .remove() lus – 50ms
Dus de .remove-lus is ongeveer 100x langzamer…….. Hmmm, misschien is een andere aanpak nodig. De snelste die ik heb gevonden is het gebruik van de lijstbegrip, maar vervang dan de inhoud van de originele lijst.
>>> def removeall_replace(x, l):
.... t = [y for y in l if y != x]
.... del l[:]
.... l.extend(t)
- removeall_replace() – 450us
Antwoord 7, autoriteit 2%
betere oplossing met lijstbegrip
x = [ i for i in x if i!=2 ]
Antwoord 8
Numpy-benadering en timing tegen een lijst/array met 1.000.000 elementen:
Timingen:
In [10]: a.shape
Out[10]: (1000000,)
In [13]: len(lst)
Out[13]: 1000000
In [18]: %timeit a[a != 2]
100 loops, best of 3: 2.94 ms per loop
In [19]: %timeit [x for x in lst if x != 2]
10 loops, best of 3: 79.7 ms per loop
Conclusie:numpy is 27 keer sneller (op mijn notebook) in vergelijking met de benadering voor het begrijpen van lijsten
PS als je je normale Python-lijst lst
naar numpy array wilt converteren:
arr = np.array(lst)
Instellen:
import numpy as np
a = np.random.randint(0, 1000, 10**6)
In [10]: a.shape
Out[10]: (1000000,)
In [12]: lst = a.tolist()
In [13]: len(lst)
Out[13]: 1000000
Controleer:
In [14]: a[a != 2].shape
Out[14]: (998949,)
In [15]: len([x for x in lst if x != 2])
Out[15]: 998949
Antwoord 9
Ten koste van de leesbaarheid, denk ik dat deze versie iets sneller is omdat het de tijd niet dwingt om de lijst opnieuw te bekijken, dus precies hetzelfde werk doen als verwijderen toch moet doen:
x = [1, 2, 3, 4, 2, 2, 3]
def remove_values_from_list(the_list, val):
for i in range(the_list.count(val)):
the_list.remove(val)
remove_values_from_list(x, 2)
print(x)
Antwoord 10
Om alle dubbele exemplaren te verwijderen en er een in de lijst te laten:
test = [1, 1, 2, 3]
newlist = list(set(test))
print newlist
[1, 2, 3]
Hier is de functie die ik heb gebruikt voor Project Euler:
def removeOccurrences(e):
return list(set(e))
Antwoord 11
a = [1, 2, 2, 3, 1]
to_remove = 1
a = [i for i in a if i != to_remove]
print(a)
Misschien niet de meest pythonische, maar toch de gemakkelijkste voor mij haha
Antwoord 12
Ik geloof dat dit waarschijnlijk sneller is dan op welke andere manier dan ook, als je niet om de volgorde van de lijsten geeft, als je voor de uiteindelijke bestelling zorgt, sla dan de indexen van het origineel op en gebruik die.
category_ids.sort()
ones_last_index = category_ids.count('1')
del category_ids[0:ones_last_index]
Antwoord 13
Laat
>>> x = [1, 2, 3, 4, 2, 2, 3]
De eenvoudigste en meest efficiënte oplossing zoals al eerder gepost is
>>> x[:] = [v for v in x if v != 2]
>>> x
[1, 3, 4, 3]
Een andere mogelijkheid die minder geheugen zou moeten gebruiken, maar langzamer zou moeten zijn, is
>>> for i in range(len(x) - 1, -1, -1):
if x[i] == 2:
x.pop(i) # takes time ~ len(x) - i
>>> x
[1, 3, 4, 3]
Timingresultaten voor lijsten met een lengte van 1000 en 100000 met 10% overeenkomende vermeldingen: 0,16 vs 0,25 ms en 23 vs 123 ms.
Antwoord 14
for i in range(a.count(' ')):
a.remove(' ')
Veel eenvoudiger geloof ik.
Antwoord 15
Verwijder alle exemplaren van een waarde uit een Python-lijst
lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list():
for list in lists:
if(list!=7):
print(list)
remove_values_from_list()
Resultaat: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11
Als alternatief,
lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list(remove):
for list in lists:
if(list!=remove):
print(list)
remove_values_from_list(7)
Resultaat: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11
Antwoord 16
Als u geen ingebouwd filter
had of geen extra ruimte wilde gebruiken en u een lineaire oplossing nodig heeft…
def remove_all(A, v):
k = 0
n = len(A)
for i in range(n):
if A[i] != v:
A[k] = A[i]
k += 1
A = A[:k]
Antwoord 17
hello = ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
#chech every item for a match
for item in range(len(hello)-1):
if hello[item] == ' ':
#if there is a match, rebuild the list with the list before the item + the list after the item
hello = hello[:item] + hello [item + 1:]
print hello
[‘h’, ‘e’, ‘l’, ‘l’, ‘o’, ‘w’, ‘o’, ‘r’, ‘l’, ‘d’]
Antwoord 18
Ik deed dit alleen voor een lijst. Ik ben maar een beginner. Een iets meer gevorderde programmeur kan zeker zo’n functie schrijven.
for i in range(len(spam)):
spam.remove('cat')
if 'cat' not in spam:
print('All instances of ' + 'cat ' + 'have been removed')
break
Antwoord 19
We kunnen ook alles ter plaatse verwijderen met behulp van del
of pop
:
import random
def remove_values_from_list(lst, target):
if type(lst) != list:
return lst
i = 0
while i < len(lst):
if lst[i] == target:
lst.pop(i) # length decreased by 1 already
else:
i += 1
return lst
remove_values_from_list(None, 2)
remove_values_from_list([], 2)
remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)], 2)
print(len(lst))
Nu voor de efficiëntie:
In [21]: %timeit -n1 -r1 x = random.randrange(0,10)
1 loop, best of 1: 43.5 us per loop
In [22]: %timeit -n1 -r1 lst = [random.randrange(0, 10) for x in range(1000000)]
g1 loop, best of 1: 660 ms per loop
In [23]: %timeit -n1 -r1 lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)]
...: , random.randrange(0,10))
1 loop, best of 1: 11.5 s per loop
In [27]: %timeit -n1 -r1 x = random.randrange(0,10); lst = [a for a in [random.randrange(0, 10) for x in
...: range(1000000)] if x != a]
1 loop, best of 1: 710 ms per loop
Zoals we zien dat in-place versie remove_values_from_list()
geen extra geheugen nodig heeft, maar het kost zoveel meer tijd om te draaien:
- 11 secondenvoor waarden voor plaatselijk verwijderen
- 710 millisecondenvoor lijstbegrippen, die een nieuwe lijst in het geheugen toewijst
Antwoord 20
Niemand heeft een optimaal antwoord gepost voor de complexiteit van tijd en ruimte, dus ik dacht dat ik het een kans zou geven. Hier is een oplossing die alle exemplaren van een specifieke waarde verwijdert zonder een nieuwe array te maken en op een efficiënte tijdcomplexiteit. Het nadeel is dat de elementen de volgordeniet behouden.
Tijdscomplexiteit: O(n)
Extra complexiteit van de ruimte: O(1)
def main():
test_case([1, 2, 3, 4, 2, 2, 3], 2) # [1, 3, 3, 4]
test_case([3, 3, 3], 3) # []
test_case([1, 1, 1], 3) # [1, 1, 1]
def test_case(test_val, remove_val):
remove_element_in_place(test_val, remove_val)
print(test_val)
def remove_element_in_place(my_list, remove_value):
length_my_list = len(my_list)
swap_idx = length_my_list - 1
for idx in range(length_my_list - 1, -1, -1):
if my_list[idx] == remove_value:
my_list[idx], my_list[swap_idx] = my_list[swap_idx], my_list[idx]
swap_idx -= 1
for pop_idx in range(length_my_list - swap_idx - 1):
my_list.pop() # O(1) operation
if __name__ == '__main__':
main()
Antwoord 21
Over de snelheid!
import time
s_time = time.time()
print 'start'
a = range(100000000)
del a[:]
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 3.25
s_time = time.time()
print 'start'
a = range(100000000)
a = []
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 2.11
Antwoord 22
p=[2,3,4,4,4]
p.clear()
print(p)
[]
Alleen met Python 3
Antwoord 23
Wat is er mis met:
Motor=['1','2','2']
For i in Motor:
If i != '2':
Print(i)
Print(motor)
Anaconda gebruiken