목록에서 모든 값을 제거 하시겠습니까?


377

파이썬에서는 remove()목록에서 처음 나타나는 값을 제거합니다.

목록에서 모든 값 을 제거하는 방법은 무엇입니까?

이것이 내가 생각한 것입니다.

>>> remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
[1, 3, 4, 3]

답변:


505

기능적 접근 :

파이썬 3.x

>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter((2).__ne__, x))
[1, 3, 3, 4]

또는

>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter(lambda a: a != 2, x))
[1, 3, 3, 4]

파이썬 2.x

>>> x = [1,2,3,2,2,2,3,4]
>>> filter(lambda a: a != 2, x)
[1, 3, 3, 4]

120
filter + lambda에 대한 목록 이해를 사용하십시오. 전자는 일반적으로 더 효율적일뿐만 아니라 더 읽기 쉽다.
habnabit

17
s / 일반적으로 / 일반적으로 /
habnabit

99
habnabit의 제안 코드는 다음과 같습니다.[y for y in x if y != 2]
coredumperror

8
나는이 솔루션을 최고라고 부르지 않을 것입니다. 코드를 훑어 보는 동안 목록 이해가 더 빠르고 이해하기 쉽습니다. 이것은 오히려 파이썬보다 펄 방식 일 것입니다.
피터 님 루트

3
직접 호출하기위한 -1 __ne__. 두 값을 비교하는 것은 단순히 호출 __eq__하거나 __ne__그중 하나를 수행하는 것보다 훨씬 복잡한 프로세스 입니다. 숫자를 비교하기 때문에 여기에서 올바르게 작동 할 수 있지만 일반적인 경우에는 정확하지 않으며 버그입니다.
Aran-Fey

211

목록 이해를 사용할 수 있습니다.

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]

7
항목을 확인하지 않고 어떻게 제거 하시겠습니까?
Alexander Ljungberg

18
원래 목록은 수정하지 않지만 새 목록을 반환합니다.
John Y

6
@Selinap : 아니요, 목록을 한 번만 검색하므로 최적입니다. 원래 코드에서 in연산자와 remove메서드는 전체 목록을 검색하여 일치하는 항목을 찾을 때까지 검색하여 목록을 여러 번 스캔합니다.
John Kugelman

4
@mhawke, @John Y : x = 대신 x [:] = ...를 사용하면 이름 'x'를 리 바인딩하지 않고 "제자리에있을 것입니다"(속도는 본질적으로 동일하고 x보다 훨씬 빠릅니다. .remove가 될 수 있습니다 !!!).
Alex Martelli

10
나는 6 년의 파이썬 후에도 여전히 람다를 이해하지 못하기 때문에 이것을 투표한다 :
Benjamin

107

효율적인 목록 이해 (또는 생성기 표현식)를 사용하면서 원래 목록을 수정해야하는 경우 슬라이스 할당을 사용할 수 있습니다.

>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> x[:] = (value for value in x if value != 2)
>>> x
[1, 3, 4, 3]

1
@Selinap : 필터는 목록을 수정하지 않고 새 목록을 반환합니다.
EM

필터 및 목록 이해는 목록을 수정하지 않습니다. 슬라이스 할당은 않습니다. 그리고 원래의 예는 그렇지 않습니다.
A. Coady

7
x가 참조하는 목록을 수정하기 때문에 이것을 좋아합니다. 해당 목록에 대한 다른 참조가 있으면 영향을받습니다. 이는 x = [ v for v in x if x != 2 ]새로운 목록을 작성하고이를 참조하도록 x를 변경하여 원래 목록을 그대로 유지 하는 제안 과 대조됩니다 .
Hannes

40

보다 추상적 인 방식으로 첫 번째 게시물의 솔루션을 반복합니다.

>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> while 2 in x: x.remove(2)
>>> x
[1, 3, 4, 3]

19
그래도 O (n * n)입니다.
Hannes

@Hannes는 루프를 한 번만 통과하고 동시에 항목을 제거하기 때문에 O (n)이되지 않습니까?
penta

1
고려하십시오 x = [1] * 10000 + [2] * 1000. 루프 본문은 1000 번 실행되며 .remove ()는 호출 될 때마다 10000 개의 요소를 건너 뛰어야합니다. 그것은 나에게 O (n * n) 냄새가 나지만 증거는 없습니다. 나는 목록의 2의 수가 길이에 비례한다고 가정하는 것이 증거라고 생각합니다. 그런 비례 계수는 큰 O 표기법에서 사라집니다. 그러나 목록에서 상수 2의 상수 중 가장 좋은 경우는 O (n ^ 2)가 아니라 O (n) 인 O (2n)입니다.
Hannes

23

간단한 해결책을보십시오

>>> [i for i in x if i != 2]

이것은 x없는 모든 요소가있는 목록을 반환합니다2


11

위의 모든 답변 (Martin Andersson의 경우 제외)은 원래 목록에서 항목을 제거하지 않고 원하는 항목없이 새 목록을 만듭니다.

>>> 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

목록에 대한 다른 참조가 있으면 중요 할 수 있습니다.

목록을 제자리에 수정하려면 다음과 같은 방법을 사용하십시오

>>> 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

속도와 관련하여 랩톱의 결과는 모두 1000 개의 항목이 제거 된 5000 개의 항목 목록에 있습니다.

  • 목록 이해-~ 400us
  • 필터-~ 900us
  • .remove () 루프-50ms

따라서 .remove 루프는 약 100 배 더 느립니다. ...... 흠, 다른 접근법이 필요할 수 있습니다. 내가 찾은 가장 빠른 것은 목록 이해를 사용하는 것이지만 원래 목록의 내용을 바꿉니다.

>>> def removeall_replace(x, l):
....    t = [y for y in l if y != x]
....    del l[:]
....    l.extend(t)
  • removeall_replace ()-450us

왜 이전 주소 아래에 새 목록을 다시 할당하지 않습니까? def remove_all(x, l): return [y for y in l if y != x]그때l = remove_all(3,l)
Dannid

@Dannid 첫 번째 코드 상자에서 두 번째 방법입니다. 새 목록을 만들고 이전 목록을 수정하지 않습니다. 목록에 대한 다른 참조는 필터링되지 않은 상태로 유지됩니다.
Paul S

아 맞아 메소드 정의에 너무 익숙해 져서 이미 수행 한 간단한 과제를 간과했습니다.
Dannid

7

당신은 이것을 할 수 있습니다

while 2 in x:   
    x.remove(2)

3
이 목록은 2 번의 n 번 발생에 대해 2 * n 번 순회해야하므로 나쁜 해결책입니다.
cxxl

순회중인 목록에서 추가하거나 제거하지 않는 것이 좋습니다. 나쁜 연습 IMHO.
Aman Mathur

5

가독성을 높이기 위해이 버전은 목록을 다시 검사하도록 강제하지 않기 때문에 약간 더 빠르다고 생각합니다. 따라서 제거 작업을 정확히 수행해야합니다.

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)

코드에 표시되는 목록의 경우이 방법은 내 측정에 따라 목록 이해 방법 (사본을 반환하는)보다 약 36 % 느립니다.
djsmith

잘 알았습니다. 그러나 나는 그것이 당신의 판단을 떨어 뜨렸다 고 생각하기 때문에, 나는 내 판을 질문 저자가 만든 첫 제안과 비교하고 있었다.
Martin Andersson

4

1.000.000 요소의 목록 / 배열에 대한 Numpy 접근 방식 및 타이밍 :

타이밍 :

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

결론 : numpy는 목록 이해 접근법에 비해 27 배 빠릅니다 (노트북에서).

일반 파이썬 목록 lst을 numpy 배열 로 변환하려면 PS :

arr = np.array(lst)

설정:

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

검사:

In [14]: a[a != 2].shape
Out[14]: (998949,)

In [15]: len([x for x in lst if x != 2])
Out[15]: 998949

4
a = [1, 2, 2, 3, 1]
to_remove = 1
a = [i for i in a if i != to_remove]
print(a)

아마도 가장 파이썬 적이지는 않지만 여전히 가장 쉬운 방법입니다.


3

중복 항목을 모두 제거하고 목록에 그대로 두려면 다음을 수행하십시오.

test = [1, 1, 2, 3]

newlist = list(set(test))

print newlist

[1, 2, 3]

Project Euler에 사용한 함수는 다음과 같습니다.

def removeOccurrences(e):
  return list(set(e))

2
250k 값을 가진 벡터 에서이 작업을 수행해야했으며 매력처럼 작동합니다.
rschwieb

1
대답은 : 예! 그리고 유능한 프로그래머에게 긴 소리가 나는 벡터가 있는지 완전히 이해합니다. 나는 솔루션을 최적화하는 것에 대해 걱정하지 않고 수학자로서 문제에 접근하며, 이는 솔루션보다 더 긴 솔루션으로 이어질 수 있습니다. (5 분 이상의 솔루션에 대한 인내심은 없지만)
rschwieb

6
목록에서 주문이 제거됩니다.
asmeurer

4
@JaredBurrows는 아마도 현재의 질문에 대답하지 않지만 상당히 다른 질문이기 때문일 것입니다.
drevicko 2016 년

6
-1, 이것은 OP의 질문에 대한 답변이 아닙니다. 완전히 다른 문제인 중복을 제거하는 솔루션입니다.
Anoyz

2

나는 당신이 목록 순서에 관심이 없다면, 최종 주문에주의를 기울이면 인덱스를 원본의 인덱스와 그에 의해 대체한다면 다른 방법보다 빠를 것이라고 생각합니다.

category_ids.sort()
ones_last_index = category_ids.count('1')
del category_ids[0:ones_last_index]

2
어디로 가는지 이해하지만이 코드는 0뿐만 아니라 시작 색인도 필요하므로 작동하지 않습니다.
Shedokan

2
for i in range(a.count(' ')):
    a.remove(' ')

훨씬 간단하게 믿습니다.


2
명확성을 높이기 위해 답을 편집하십시오. 권장 코드가 정확히 무엇을 수행하는지, 왜 작동하는지, 이것이 왜 추천인지를 분명히하십시오. 코드가 나머지 답변과 명확하게 식별되도록 질문의 형식을 올바르게 지정하십시오.
Ortund

2

허락하다

>>> x = [1, 2, 3, 4, 2, 2, 3]

이미 게시 된 가장 간단하고 효율적인 솔루션은

>>> x[:] = [v for v in x if v != 2]
>>> x
[1, 3, 4, 3]

더 적은 메모리를 사용해야하지만 느려질 수있는 또 다른 가능성은

>>> 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]

일치 항목이 10 % 인 길이 1000 및 100000의 목록에 대한 타이밍 결과 : 0.16 vs 0.25 ms 및 23 vs 123 ms

길이가 1000 인 타이밍

길이가 100000 인 타이밍


1

파이썬 목록에서 모든 값을 제거하십시오.

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()

결과: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11

또는

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)

결과: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11


"100 % 정확도로 작동하는 함수 내에서 '각 if 루프마다'파이썬이 필요하다! '
rafiqul786

당신은 단지 요소를 인쇄하는 목록을 수정하지 않습니다. 또한 혼란 목록과 같은 목록을 이름
KON 정신

0

내장 filter이 없거나 여분의 공간을 사용하고 싶지 않고 선형 솔루션이 필요한 경우 ...

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]

0
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']


설명을 통해 답을 정교하게 작성하십시오.
parlad

0

방금 목록을 작성했습니다. 나는 단지 초보자입니다. 약간 더 고급 인 프로그래머라면 반드시 이와 같은 함수를 작성할 수 있습니다.

for i in range(len(spam)):
    spam.remove('cat')
    if 'cat' not in spam:
         print('All instances of ' + 'cat ' + 'have been removed')
         break

0

del또는 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))

이제 효율성을 위해 :

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

전체 버전 remove_values_from_list()에는 추가 메모리가 필요하지 않지만 실행하는 데 훨씬 많은 시간이 걸립니다.

  • 전체 제거 값은 11 초 입니다.
  • 메모리에 새로운리스트를 할당하는리스트 이해를위한 710 밀리 초

0

시간과 공간의 복잡성에 대한 최적의 답변을 게시 한 사람은 아무도 없으므로 한 번에 해결하겠다고 생각했습니다. 다음은 새로운 배열을 작성하지 않고 효율적인 시간 복잡성으로 특정 값의 모든 항목을 제거하는 솔루션입니다. 단점은 요소가 순서를 유지하지 못한다는 것 입니다.

시간 복잡성 : O (n)
추가 공간 복잡성 : 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()

-1

속도에 대해!

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

-3
p=[2,3,4,4,4]
p.clear()
print(p)
[]

파이썬 3에서만


2
유감스럽게도, 이것은 질문의 범위 내에 있으며 정확합니다.
Erich

그것이 올바른지 모르겠습니다. 이 제거됩니다 모든 항목을 목록에서없는 값의 모든 발생 .
조지

-3

무엇이 잘못 되었나요?

Motor=['1','2','2']
For i in Motor:
       If i  != '2':
       Print(i)
Print(motor)

아나콘다 사용하기


2
다른 사용자가 그 기능을 이해할 수 있도록 코드 줄을 설명하십시오. 감사!
이그나시오 아라

이 코드는 목록에서 아무것도 제거 하지 않습니다 .
조지
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.