[python] 단 하나의 명령문으로 Python 목록에서 여러 항목 제거

파이썬에서는 목록에서 항목을 제거하는 방법을 알고 있습니다.

item_list = ['item', 5, 'foo', 3.14, True]
item_list.remove('item')
item_list.remove(5)

위의 코드는 item_list에서 값 5와 ‘item’을 제거합니다. 하지만 제거 할 내용이 많으면 여러 줄을 써야합니다.

item_list.remove("something_to_remove")

제거중인 항목의 색인을 알고 있으면 다음을 사용합니다.

del item_list[x]

여기서 x는 제거하려는 항목의 인덱스입니다.

제거하려는 모든 숫자의 인덱스를 알고 있으면 인덱스의 del항목에 대해 일종의 루프를 사용 합니다.

하지만 제거하려는 항목의 색인을 모르는 경우 어떻게해야합니까?

나는 시도 item_list.remove('item', 'foo')했지만 remove하나의 인수 만 취 한다는 오류가 발생했습니다 .

단일 명령문의 목록에서 여러 항목을 제거하는 방법이 있습니까?

PS 내가 사용 del하고 remove. 누군가이 둘의 차이점을 설명 할 수 있습니까, 아니면 동일합니까?

감사



답변

Python에서는 새 개체를 만드는 것이 기존 개체를 수정하는 것보다 낫습니다.

item_list = ['item', 5, 'foo', 3.14, True]
item_list = [e for e in item_list if e not in ('item', 5)]

다음과 같습니다.

item_list = ['item', 5, 'foo', 3.14, True]
new_list = []
for e in item_list:
    if e not in ('item', 5):
        new_list.append(e)
item_list = new_list

필터링 된 값의 큰 목록 (여기서는 ('item', 5)작은 요소 집합)의 set경우 in작업이 O (1)에 있으므로 a 를 사용하면 성능이 향상 될 수 있습니다 .

item_list = [e for e in item_list if e not in {'item', 5}]

주석에서 설명하고 여기 에 제안 된 대로 다음은 각 루프에서 빌드되는 세트를 피하면서 훨씬 더 많은 시간을 절약 할 수 있습니다.

unwanted = {'item', 5}
item_list = [e for e in item_list if e not in unwanted]

꽃 필터는 메모리가 저렴하지 않은 경우 또한 좋은 솔루션입니다.


답변

item_list = ['item', 5, 'foo', 3.14, True]
list_to_remove=['item', 5, 'foo']

제거 후 최종 목록은 다음과 같아야합니다.

final_list=[3.14, True]

단일 라인 코드

final_list= list(set(item_list).difference(set(list_to_remove)))

출력은 다음과 같습니다.

final_list=[3.14, True]


답변

왜 모두 set가 파이썬에서 s 의 놀라운 기능을 언급하는 것을 잊었는지 모르겠습니다 . 목록을 세트로 캐스트 한 다음 다음과 같은 간단한 표현식에서 제거 할 항목을 제거 할 수 있습니다.

>>> item_list = ['item', 5, 'foo', 3.14, True]
>>> item_list = set(item_list) - {'item', 5}
>>> item_list
{True, 3.14, 'foo'}
>>> # you can cast it again in a list-from like so
>>> item_list = list(item_list)
>>> item_list
[True, 3.14, 'foo']


답변

나는 여기에도 맞는 것을 보았 기 때문에 여기 에서 내 대답을 다시 게시 하고 있습니다. 여러 값을 제거하거나 이러한 값의 중복 만 제거 할 수 있으며 새 목록을 반환하거나 주어진 목록을 제자리에서 수정합니다.


def removed(items, original_list, only_duplicates=False, inplace=False):
    """By default removes given items from original_list and returns
    a new list. Optionally only removes duplicates of `items` or modifies
    given list in place.
    """
    if not hasattr(items, '__iter__') or isinstance(items, str):
        items = [items]

    if only_duplicates:
        result = []
        for item in original_list:
            if item not in items or item not in result:
                result.append(item)
    else:
        result = [item for item in original_list if item not in items]

    if inplace:
        original_list[:] = result
    else:
        return result

독 스트링 확장 :

"""
Examples:
---------

    >>>li1 = [1, 2, 3, 4, 4, 5, 5]
    >>>removed(4, li1)
       [1, 2, 3, 5, 5]
    >>>removed((4,5), li1)
       [1, 2, 3]
    >>>removed((4,5), li1, only_duplicates=True)
       [1, 2, 3, 4, 5]

    # remove all duplicates by passing original_list also to `items`.:
    >>>removed(li1, li1, only_duplicates=True)
      [1, 2, 3, 4, 5]

    # inplace:
    >>>removed((4,5), li1, only_duplicates=True, inplace=True)
    >>>li1
        [1, 2, 3, 4, 5]

    >>>li2 =['abc', 'def', 'def', 'ghi', 'ghi']
    >>>removed(('def', 'ghi'), li2, only_duplicates=True, inplace=True)
    >>>li2
        ['abc', 'def', 'ghi']
"""

정말로하고 싶은 일에 대해 명확히하고, 기존 목록을 수정하거나, 특정 항목이 누락 된 새 목록을 만들어야합니다. 기존 목록을 가리키는 두 번째 참조가있는 경우이를 구분하는 것이 중요합니다. 예를 들어 …

li1 = [1, 2, 3, 4, 4, 5, 5]
li2 = li1
# then rebind li1 to the new list without the value 4
li1 = removed(4, li1)
# you end up with two separate lists where li2 is still pointing to the 
# original
li2
# [1, 2, 3, 4, 4, 5, 5]
li1
# [1, 2, 3, 5, 5]

이것은 당신이 원하는 행동 일 수도 있고 아닐 수도 있습니다.


답변

itertools 모듈 에서 filterfalse 함수를 사용할 수 있습니다.

import random
from itertools import filterfalse

random.seed(42)

data = [random.randrange(5) for _ in range(10)]
clean = [*filterfalse(lambda i: i == 0, data)]
print(f"Remove 0s\n{data=}\n{clean=}\n")


clean = [*filterfalse(lambda i: i in (0, 1), data)]
print(f"Remove 0s and 1s\n{data=}\n{clean=}")

산출:

Remove 0s
data=[0, 0, 2, 1, 1, 1, 0, 4, 0, 4]
clean=[2, 1, 1, 1, 4, 4]

Remove 0s and 1s
data=[0, 0, 2, 1, 1, 1, 0, 4, 0, 4]
clean=[2, 4, 4]


답변

하지만 제거하려는 항목의 색인을 모르는 경우 어떻게해야합니까?

.remove를 좋아하지 않는 이유를 정확히 이해하지 못하지만 값에 해당하는 첫 번째 색인을 얻으려면 .index (value)를 사용하십시오.

ind=item_list.index('item')

그런 다음 해당 값을 제거하십시오.

del item_list.pop[ind]

.index (value)는 첫 번째 값을 가져오고 .remove (value)는 첫 번째 값을 제거합니다.


답변

이것을 사용할 수 있습니다-

목록이 있다고 가정 해 보겠습니다. l = [1,2,3,4,5]

단일 명령문에서 마지막 두 항목을 삭제하려고합니다.

del l[3:]

출력이 있습니다.

l = [1,2,3]

단순하게 유지