Python列表删除多个项目

Python列表删除多个项目,python,python-3.x,list,Python,Python 3.x,List,我试图从列表中删除一个值的多次出现。输出不会删除任何所需的项 def rem(a,li): try: while a in li == True: li.remove(a) print('Updated list: ',li) except ValueError: print(a,' is not located in the list ',li) 尝试函数的示例: L = [1,2,3,45,3,2,3,3,4,5] 雷姆(2,L) 输出:更新的列表

我试图从列表中删除一个值的多次出现。输出不会删除任何所需的项

def rem(a,li):
try:
    while a in li == True:
        li.remove(a)
    print('Updated list: ',li)
except ValueError:
    print(a,' is not located in the list ',li)
尝试函数的示例:

L = [1,2,3,45,3,2,3,3,4,5]
雷姆(2,L)


输出:更新的列表:[1,2,3,45,3,2,3,3,4,5]

尝试将while条件更改为
,而a在li中

def rem(a,li):
    try:
        while a in li:
            li.remove(a)
        print('Updated list: ',li)
    except ValueError:
        print(a,' is not located in the list ',li)

L = [1,2,3,45,3,2,3,3,4,5]
rem(2,L)

通常,如果要从列表中删除重复项,则可以使用内置的

假设要从
L
中删除
a
的所有实例,也可以使用简单的列表理解:

def rem(a,li):
    return [x for x in li if x != a]

L = [1,2,3,45,3,2,3,3,4,5]
print(rem(2,L))
哪些产出:

[1, 3, 45, 3, 3, 3, 4, 5]

对于理解列表来说,这将是一个更好的工作。
L[:]=[a代表L中的a,如果a不在(2,)]
分配给切片将使列表发生变化



我正在更新我的答案,以解释你的问题所允许的各种解释 并通过同时接受要删除的字符串和多个值,使其更加通用

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]

这可能是您想要的行为,也可能不是。

代码中有两个错误。第一个是

当li==True时:
实际上,该检查总是返回False,因为
li==True
False

它实际上应该是
while(li中的a)==True:
,或者
while a in li:

此外,如果您试图仅删除重复出现的
a
(即将第一次出现的
a
保留在中),则列表理解将无法满足您的需要。您必须在
rem()
函数中添加一个额外的检查,以捕获第一次出现的
a
,然后执行循环:

def rem(a, li):
  list_length = len(li)
  i = 0
  while (li[i] != a) and (i < list_length):
    i += 1              # skip to the first occurrence of a in li
  i += 1                # increment i 
  while i < list_length:
    if li[i] == a:
      del li[i]
      print('Updated list: ', li)
      list_length -= 1          # decrement list length after removing occurrence of a
    else:
      i += 1
def rem(a,li):
列表长度=长度(li)
i=0
而(li[i]!=a)和(i<列表长度):
i+=1#跳到li中第一个出现的a
i+=1#增量i
而i

上面的代码片段不包括列表为空的边缘情况,或者列表中不包含案例
a
。我将把这些练习留给你。

只需跟踪索引编号并使用
del

简单方法:

L = [1,2,3,45,3,2,3,3,4,5]

def rem(a,li):
    for j,i in enumerate(li):
        if a==i:
            del li[j]

    return li



print(rem(2,L))
输出:

[1, 3, 45, 3, 3, 3, 4, 5]

是否打算完全删除该值?或者你只是想减少一个实例。你期望的结果是什么?您是要删除所有出现的
a
还是只删除重复出现的?e、 g.如果
lst=[1,2,3,4,5,5]
并且您调用
rem(5,lst)
,您是否期望输出
[1,2,3,4,5]
[1,2,3,4]
?谢谢您的工作。python是否将li中的a解释为已经包含了等于True的比较?这是我能从代码中推断出的唯一逻辑。@evan是的,你说得对!从其他答案可以看出,有更好的方法可以做到这一点。尝试的目的是什么…除了?当a在li
中时,您已经有了
,因此当调用
li.remove(a)
时,
a
必须在
li
中。什么时候会发生
ValueError
?(为获得可接受的答案,应删除不必要的代码)@abccd感谢您的反馈;这个概念对我来说是很新的,以后还会继续。如果你不在乎是否创建了一个新的列表,这是没有必要的,但问题的措辞我理解他想要的是改变列表,而不是替换它。您可以使用
id(L)
检查列表在分配给切片时是否仍然与以前相同,同时它会获得一个新的id,以防您跳过切片。对于这样一个简单的任务来说,这相当复杂。