다른 목록에서 한 목록을 빼려면 어떻게 해야 합니까?
목록 간의 차이를 확인하고 싶습니다.x
그리고.y
:
>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> y = [1, 3, 5, 7, 9]
>>> x - y
# should return [0, 2, 4, 6, 8]
목록 이해력을 사용하여 원래 순서를 유지하면서 차이를 계산합니다.x
:
[item for item in x if item not in y]
목록 속성(예: 순서 지정)이 필요하지 않은 경우, 다른 답변에서 제안하는 것처럼 설정된 차이를 사용합니다.
list(set(x) - set(y))
허하기용을 하는 것x - y
구문, 문구, 재의를 재정의합니다.__sub__
에서 물려받은 계급에.list
:
class MyList(list):
def __init__(self, *args):
super(MyList, self).__init__(args)
def __sub__(self, other):
return self.__class__(*[item for item in self if item not in other])
용도:
x = MyList(1, 2, 3, 4)
y = MyList(2, 5, 2)
z = x - y
>>> z = list(set(x) - set(y))
>>> z
[0, 8, 2, 4, 6]
또는 변환을 수행할 필요가 없도록 x 및 y 집합이 있을 수 있습니다.
중복 및 주문 항목이 문제인 경우:
[i for i in a if not i in b or b.remove(i)]
a = [1,2,3,3,3,3,4]
b = [1,3]
result: [2, 3, 3, 3, 4]
그것은 "감산 설정" 연산입니다.설정된 데이터 구조를 사용합니다.
Python 2.7의 경우:
x = {1,2,3,4,5,6,7,8,9,0}
y = {1,3,5,7,9}
print x - y
출력:
>>> print x - y
set([0, 8, 2, 4, 6])
많은 사용 사례에서 원하는 답은 다음과 같습니다.
ys = set(y)
[item for item in x if item not in ys]
이것은 아론스터링의 대답과 양자 사이의 잡종입니다.수프의 답.
의 버전은 애링버전은터스애런버▁aaron은전▁does링터▁version애스.len(y)
의 각 에 대한 x
그래서 2차 시간이 걸립니다.양자의Soup의세트를 에 Soup의 각 세트 조회를 합니다.x
—하지만, 둘 다 변환하기 때문입니다. x
그리고.y
집합으로, 그것은 당신의 요소의 순서를 잃습니다.
▁only해만 y
한 세트로, 그리고 반복.x
순서대로 선형 시간과 순서 보존이라는 두 가지 이점을 모두 얻을 수 있습니다.*
하지만, 이것은 여전히 양자로부터 문제가 있습니다.수프 버전:요소를 해시할 수 있어야 합니다.그것은 세트의 본질에 거의 내재되어 있습니다.예를 들어, 다른 딕트 목록에서 딕트 목록을 빼려고 하지만 뺄 목록이 크면 어떻게 합니까?
만약 여러분이 가치관을 해시 가능한 방식으로 장식할 수 있다면, 그것은 문제를 해결할 수 있습니다.예를 들어 값 자체가 해시 가능한 플랫 사전의 경우:
ys = {tuple(item.items()) for item in y}
[item for item in x if tuple(item.items()) not in ys]
유형이 좀 더 복잡하더라도(예: 해시 가능한 JSON 호환 값이나 값이 재귀적으로 동일한 유형인 목록 또는 딕트) 이 솔루션을 계속 사용할 수 있습니다.그러나 일부 유형은 해시 가능한 것으로 변환할 수 없습니다.
가능하지 만들 가능하다면 시간log-linear time) 을 얻을 수 .O(N*log M)
보다 훨씬 더 .O(N*M)
리스트 솔루션의 시간, 그러나 그것만큼 좋지는 않습니다.O(N+M)
으로써 사용할 수 있습니다.bisect
:
ys = sorted(y)
def bisect_contains(seq, item):
index = bisect.bisect(seq, item)
return index < len(seq) and seq[index] == item
[item for item in x if bisect_contains(ys, item)]
항목이 해시 가능하지도 않고 비교 가능하지도 않은 경우 2차 솔루션을 고수해야 합니다.
한 쌍을 사용하여 이 작업을 수행할 수도 있습니다.OrderedSet
요리법 및 타사 모듈을 찾을 수 있는 개체입니다.하지만 저는 이것이 더 간단하다고 생각합니다.
설정 검색이 일정한 시간인 이유는 값을 해시하고 해당 해시에 대한 항목이 있는지 확인하기만 하면 되기 때문입니다.값을 해시할 수 없으면 작동하지 않습니다.
목록에서 중복 요소를 허용하는 경우 컬렉션의 카운터를 사용할 수 있습니다.
from collections import Counter
result = list((Counter(x)-Counter(y)).elements())
x의 요소 순서를 유지해야 하는 경우:
result = [ v for c in [Counter(y)] for v in x if not c[v] or c.subtract([v]) ]
다른 솔루션에는 몇 가지 문제 중 하나가 있습니다.
- 그들은 질서를 유지하지 않습니다.
- 요소의 를 들어, 를들어개요, 정한의제않습다니지거하소를수예확,▁they다않습니▁of▁e,.
x = [1, 2, 2, 2]
그리고.y = [2, 2]
그들은 개종합니다.y
set
일치하는합니다.[1]
only) 각 요소)를합니다.[1, 2, 2]
), 제거합니다.2
번, 두번는, 나것떠것을 남김[1, 2]
또는 - 그들은 합니다.
O(m * n)
O(m + n)
일하다.
Alain은 #2와 #3을 해결하기 위해 올바른 방향으로 가고 있었지만, 그 해결책은 순서를 잃게 될 것입니다.순서를 보존하는 솔루션(첫 번째 솔루션 제거)n
에 대한 각 n
의 list
제거할 값 중)은 다음과 같습니다.
from collections import Counter
x = [1,2,3,4,3,2,1]
y = [1,2,2]
remaining = Counter(y)
out = []
for val in x:
if remaining[val]:
remaining[val] -= 1
else:
out.append(val)
# out is now [3, 4, 3, 1], having removed the first 1 and both 2s.
각 요소의 마지막 복사본을 제거하려면 다음을 변경합니다.for
로 루프하다.for val in reversed(x):
가추를 합니다.out.reverse()
료직후에서 나온 에.for
루우프
의 Counter
이라O(n)
y
의 길이,의길, 복반x
이라O(n)
x
의 길이, 의길이, 고리그고Counter
는 멤십테돌이는연변와트스버는▁members.O(1)
,하는 동안에list.append
상각됩니다.O(1)
(주어진진)append
수 있습니다.O(n)
그러나 많은 사람들에게는append
평균, 전체빅평균오평.O(1)
재할당이 필요한 경우가 점점 더 적기 때문에), 따라서 수행되는 전체 작업은 다음과 같습니다.O(m + n)
.
에 대한 테스트를 수행하여 에 요소가 있었는지 확인할 수도 있습니다.y
에서 되지 않은.x
테스트를 통해:
remaining = +remaining # Removes all keys with zero counts from Counter
if remaining:
# remaining contained elements with non-zero counts
집합에서 값을 조회하는 것이 목록에서 값을 조회하는 것보다 빠릅니다.
[item for item in x if item not in set(y)]
다음보다 확장성이 조금 더 좋을 것으로 생각합니다.
[item for item in x if item not in y]
둘 다 목록의 순서를 유지합니다.
세트 메소드를 사용하여 두 목록 간의 차이를 찾을 수도 있습니다.
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
y = [1, 3, 5, 7, 9]
list(set(x).difference(y))
[0, 2, 4, 6, 8]
이거 먹어봐요.
def subtract_lists(a, b):
""" Subtracts two lists. Throws ValueError if b contains items not in a """
# Terminate if b is empty, otherwise remove b[0] from a and recurse
return a if len(b) == 0 else [a[:i] + subtract_lists(a[i+1:], b[1:])
for i in [a.index(b[0])]][0]
>>> x = [1,2,3,4,5,6,7,8,9,0]
>>> y = [1,3,5,7,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0]
>>> x = [1,2,3,4,5,6,7,8,9,0,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0, 9] #9 is only deleted once
>>>
제공하는 은 좋아기본 인 @aaronasterling과 .x = MyList(1, 2, 3, 4)
대x = MyList([1, 2, 3, 4])
따라서 아래의 코드를 파이썬 리스트에 더 친숙하게 사용할 수 있습니다.
class MyList(list):
def __init__(self, *args):
super(MyList, self).__init__(*args)
def __sub__(self, other):
return self.__class__([item for item in self if item not in other])
예:
x = MyList([1, 2, 3, 4])
y = MyList([2, 5, 2])
z = x - y
from collections import Counter
y = Counter(y)
x = Counter(x)
print(list(x-y))
다음을 수행합니다.
>>> xs = [1, 2, 3, 4, 3, 2, 1]
>>> ys = [1, 3, 3]
을 한 xs - ys == {2, 4}
설정된 차이를 취합니다.
>>> set(xs) - set(ys)
{2, 4}
발생 항목 xs - ys == [2, 4, 2]
>>> [x for x in xs if x not in ys]
[2, 4, 2]
한다면ys
큼, 변환1 전용 ys
성능을 로: 다음과 같이 구성됩니다.
>>> ys_set = set(ys)
>>> [x for x in xs if x not in ys_set]
[2, 4, 2]
의 발생만 합니다.xs - ys == [2, 4, 2, 1]
from collections import Counter, defaultdict
def diff(xs, ys):
counter = Counter(ys)
for x in xs:
if counter[x] > 0:
counter[x] -= 1
continue
yield x
>>> list(diff(xs, ys))
[2, 4, 2, 1]
1 변환 중xs
set
것은 는 한 xs
.
이 예에서는 두 개의 목록을 뺍니다.
# List of pairs of points
list = []
list.append([(602, 336), (624, 365)])
list.append([(635, 336), (654, 365)])
list.append([(642, 342), (648, 358)])
list.append([(644, 344), (646, 356)])
list.append([(653, 337), (671, 365)])
list.append([(728, 13), (739, 32)])
list.append([(756, 59), (767, 79)])
itens_to_remove = []
itens_to_remove.append([(642, 342), (648, 358)])
itens_to_remove.append([(644, 344), (646, 356)])
print("Initial List Size: ", len(list))
for a in itens_to_remove:
for b in list:
if a == b :
list.remove(b)
print("Final List Size: ", len(list))
list1 = ['a', 'c', 'a', 'b', 'k']
list2 = ['a', 'a', 'a', 'a', 'b', 'c', 'c', 'd', 'e', 'f']
for e in list1:
try:
list2.remove(e)
except ValueError:
print(f'{e} not in list')
list2
# ['a', 'a', 'c', 'd', 'e', 'f']
그러면 list2가 변경됩니다.만약 당신이 list2를 보호하고 싶다면, 그것을 복사하고 이 코드에서 list2의 복사본을 사용하세요.
def listsubtraction(parent,child):
answer=[]
for element in parent:
if element not in child:
answer.append(element)
return answer
이게 통해야 할 것 같아요.제가 초보자라 실수가 있으면 용서해 주세요.
언급URL : https://stackoverflow.com/questions/3428536/how-do-i-subtract-one-list-from-another
'programing' 카테고리의 다른 글
클래스 __dict_가 매핑 프록시인 이유는 무엇입니까? (0) | 2023.05.11 |
---|---|
Linux에서 Bash를 사용하여 모든 출력을 파일로 리디렉션하시겠습니까? (0) | 2023.05.11 |
Visual Studio 2010 - XAML 편집기의 속도가 매우 느립니다. (0) | 2023.05.11 |
Lodash를 사용하여 목록에서 요소를 제거하려면 어떻게 해야 합니까? (0) | 2023.05.11 |
C# 디렉터리에 있는 모든 파일을 재귀적으로 나열하는 방법은 무엇입니까? (0) | 2023.05.11 |