programing

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

lastmoon 2023. 4. 17. 22:16
반응형

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

목록 내의 모든 값을 다른 목록에서 삭제할 방법을 찾고 있습니다.

다음과 같은 경우:

a = range(1,10)  
a.remove([2,3,7])  
print a  
a = [1,4,5,6,8,9]  
>>> a = range(1, 10)
>>> [x for x in a if x not in [2, 3, 7]]
[1, 4, 5, 6, 8, 9]

저는 그 주제를 빠르게 할 수 있는 방법을 찾고 있었기 때문에 제안된 방법으로 몇 가지 실험을 했습니다.그리고 저는 결과에 놀랐기 때문에 여러분들과 함께 공유하고 싶습니다.

실험은 pythonbenchmark 도구를 사용하여 수행되었으며

a = range(1,50000) # Source list
b = range(1,15000) # Items to remove

결과:

 def comprehension(a, b):
     return [x for x in a if x not in b]

5회 시도, 평균 시간 12.8초

def filter_function(a, b):
    return filter(lambda x: x not in b, a)

5회 시도, 평균 시간 12.6초

def modification(a,b):
    for x in b:
        try:
            a.remove(x)
        except ValueError:
            pass
    return a

5회 시도, 평균 시간 0.27초

def set_approach(a,b):
    return list(set(a)-set(b))

5회 시도, 평균 시간 0.0057초

또한 마지막 두 함수의 입력 크기를 더 크게 측정했습니다.

a = range(1,500000)
b = range(1,100000)

그 결과:

수정(제거 방법)의 경우 - 평균 시간은 252초입니다. 설정 접근의 경우 - 평균 시간은 0.75초입니다.

즉, 세트에 대한 접근 방식이 다른 접근 방식보다 훨씬 빠르다는 것을 알 수 있습니다.네, 비슷한 물건은 보관하지 않지만, 필요없으시다면 고객님께 드리는 겁니다.또한 목록 이해와 필터 기능 사용에는 거의 차이가 없습니다.'제거'를 사용하면 최대 50배 더 빠르지만 소스 목록을 수정합니다.그리고 최상의 선택은 세트를 사용하는 것입니다. 목록 이해보다 1000배 이상 빠릅니다!

반복 값이 없는 경우 설정 차이를 사용할 수 있습니다.

x = set(range(10))
y = x - set([2, 3, 7])
# y = set([0, 1, 4, 5, 6, 8, 9])

필요한 경우 목록으로 다시 변환합니다.

a = range(1,10)
itemsToRemove = set([2, 3, 7])
b = filter(lambda x: x not in itemsToRemove, a)

또는

b = [x for x in a if x not in itemsToRemove]

내부에는 세트를 작성하지 마십시오.lambda이해력 안에서도요이렇게 하면 반복할 때마다 다시 생성되어 세트를 사용하는 요점이 전혀 사라집니다.

가장 간단한 방법은

>>> a = range(1, 10)
>>> for x in [2, 3, 7]:
...  a.remove(x)
... 
>>> a
[1, 4, 5, 6, 8, 9]

여기서 생각할 수 있는 문제 중 하나는 remove()를 호출할 때마다 모든 항목이 목록 아래로 이동하여 구멍을 메우는 것입니다.그래서 만약에a매우 커지게 됩니다. 이것은 매우 느려질 것입니다.

이렇게 하면 새 목록이 작성됩니다.장점은 첫 번째 접근 방식의 모든 혼란을 피할 수 있다는 것입니다.

>>> removeset = set([2, 3, 7])
>>> a = [x for x in a if x not in removeset]

수정하는 경우a1개의 작은 변경만 있으면 됩니다.

>>> removeset = set([2, 3, 7])
>>> a[:] = [x for x in a if x not in removeset]

다른 사람들은 예를 들어 필터링 후 새 목록을 만드는 방법을 제안했습니다.

newl = [x for x in l if x not in [2,3,7]]

또는

newl = filter(lambda x: x not in [2,3,7], l) 

그러나 당신의 질문에서 당신이 이것을 할 수 있도록 일괄 수정을 원하는 것처럼 보입니다.원래 목록이 길고 삭제되는 항목이 적으면 이 작업도 훨씬 더 빠릅니다.

l = range(1,10)
for o in set([2,3,7,11]):
    try:
        l.remove(o)
    except ValueError:
        pass

print l

출력: [1, 4, 5, 6, 8, 9]

ValueError 예외를 확인하고 있기 때문에 항목이 Orginal List에 없어도 동작합니다.

내부 하지 않은 S.Mark더 심플합니다.

>>> a=range(1,10)
>>> for i in [2,3,7]: a.remove(i)
...
>>> a
[1, 4, 5, 6, 8, 9]

>>> a=range(1,10)
>>> b=map(a.remove,[2,3,7])
>>> a
[1, 4, 5, 6, 8, 9]

언급URL : https://stackoverflow.com/questions/2514961/remove-all-values-within-one-list-from-another-list

반응형