Python 목록 감산 작업
난 이런 걸 원해:
>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> y = [1, 3, 5, 7, 9]
>>> y - x
# should return [2,4,6,8,0]
목록 이해 사용:
[item for item in x if item not in y]
를 사용하는 경우-
infix 구문에서는 다음 작업을 수행할 수 있습니다.
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]
이것은 "set 뺄셈" 연산입니다.이를 위해 설정된 데이터 구조를 사용합니다.
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]
이것은 애러너슬링의 대답과 양자 사이의 혼합이다.수프의 답.
애러나스터링 버전은len(y)
의 각 요소에 대한 항목 비교x
그래서 2차 시간이 걸립니다.양자Soup의 버전은 세트를 사용하기 때문에 Soup의 각 요소에 대해 단일 상수 시간 세트 조회를 수행합니다.x
--다만, 양쪽 모두를 변환하기 위해서입니다. x
그리고.y
세트로 나누면 요소의 순서가 없어집니다.
변환 전용y
한 세트로, 그리고 반복한다.x
선형 시간과 순서 보존이라는 두 가지 장점을 모두 누릴 수 있습니다.*
하지만, 이것은 여전히 양자적인 문제를 가지고 있다.수프 버전:요소를 해시할 수 있어야 합니다.그것은 세트장의 본질에 거의 포함되어 있습니다.** 예를 들어 다른 딕트 목록에서 딕트 목록을 빼려고 하는데 빼야 할 목록이 큰 경우 어떻게 해야 합니까?
해시 가능한 방식으로 자신의 가치를 꾸밀 수 있다면 문제가 해결됩니다.예를 들어, 값 자체가 해시 가능한 플랫 사전의 경우:
ys = {tuple(item.items()) for item in y}
[item for item in x if tuple(item.items()) not in ys]
유형이 좀 더 복잡한 경우(예를 들어 해시 가능한 JSON 호환 값이나 값이 반복적으로 동일한 유형의 값을 나열하거나 받아쓰기 등) 이 솔루션을 사용할 수 있습니다.하지만 해시 가능한 것으로 변환할 수 없는 유형도 있습니다.
아이템이 해시 가능하지 않고 만들 수 없는 경우, 적어도 로그 선형 시간을 얻을 수 있습니다(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차 해를 사용할 수 없습니다.
* 이 조작에는, 다음의 2개의 페어를 사용할 수도 있습니다.OrderedSet
오브젝트 - 레시피와 서드파티 모듈을 찾을 수 있습니다.하지만 나는 이것이 더 간단하다고 생각한다.
** set lookups가 일정한 시간인 이유는 값을 해시하고 해당 해시 엔트리가 있는지 확인하기만 하면 되기 때문입니다.값을 해시할 수 없는 경우, 이것은 동작하지 않습니다.
목록에서 중복 요소를 허용하는 경우 컬렉션의 카운터를 사용할 수 있습니다.
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]) ]
이것을 실현하는 가장 쉬운 방법은 set()를 사용하는 것이라고 생각합니다.
>>> x = [1,2,3,4,5,6,7,8,9,0]
>>> y = [1,3,5,7,9]
>>> list(set(x)- set(y))
[0, 2, 4, 6, 8]
다른 솔루션에는 몇 가지 문제가 있습니다.
- 질서를 지키지 않거나
- 요소 수를
x = [1, 2, 2, 2]
★★★★★★★★★★★★★★★★★」y = [2, 2]
y
a까지set
하는 모든 「」 「」 「」 「」)를[1]
요소, 1개)를 하나씩 합니다.[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
로 to에 for val in reversed(x):
out.reverse()
「」의 for
loopsyslog.syslog..syslog.
「 」의 Counter
O(n)
면측으로 y
의 길이, 「」, 「」를 반복합니다x
O(n)
면측으로 x
의 및 " " " "Counter
및 은 """입니다.O(1)
와 동시에 , 「」를 참조해 주세요.list.append
O(1)
(기정)append
수 있습니다.O(n)
, 많은 님의 append
s, "big-O"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]
둘 다 목록의 순서를 유지합니다.
값이 일의인 경우는, 다음과 같이 시험할 수도 있습니다.
list(set(x) - set(y))
이거 먹어봐.
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
>>>
설정 방법을 사용하여 두 목록의 차이를 찾을 수도 있습니다.
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]
@은 좋아 목록의인 @aaronasterling과 .x = MyList(1, 2, 3, 4)
»x = MyList([1, 2, 3, 4])
따라서 아래 코드는 보다 python-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
다음 예제에서는 두 가지 목록을 뺍니다.
# 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))
from collections import Counter
y = Counter(y)
x = Counter(x)
print(list(x-y))
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를 복사하고 이 코드에서 list2의 복사본을 사용하십시오.
언급URL : https://stackoverflow.com/questions/3428536/python-list-subtraction-operation
'programing' 카테고리의 다른 글
jQuery에서 div 요소 만들기 (0) | 2022.10.10 |
---|---|
jQuery: jQuery에서 숨겨진 요소의 높이를 가져옵니다. (0) | 2022.10.10 |
yaml의 빈 필드 (0) | 2022.10.10 |
이 버전의 MariaDB는 아직 'LIMIT & IN / ALL / ANY / SOME 서브쿼리'를 지원하지 않습니다.여러 WHERE 및 LIMITS (0) | 2022.10.10 |
팬더 MultiIndex DataFrame에서 행 선택 (0) | 2022.10.10 |