不改变列表的情况下删除元素

79
假设您有一个列表。
>>> m = ['a','b','c']

我想创建一个新的列表n,该列表包含除给定项m中的某一项(例如项'a')之外的所有内容。然而,当我使用

>>> m.remove('a')
>>> m
m = ['b', 'c']

原始列表已被改变(值'a'从原始列表中删除)。 有没有一种方法可以获得一个新列表,不改变原始列表的情况下去掉'a'? 所以我的意思是m仍应该是['a','b','c'],我将获得一个列表,必须是['b','c']


2
你想要的最终结果是什么?你可以使用 m[:] 将 m 复制到一个新列表中。 - Ben
1
你的意思是从列表中移除某个元素,但不改变列表本身吗?还是你的意思是用一种空表示来替换列表中的一个项目,以便索引不会改变? - Dan Oberlam
是的,我的意思是在不改变列表的情况下删除某些东西。 - user3457749
你的意思是 my_var = m[0] 吗? - Padraic Cunningham
8个回答

98

我猜你的意思是想要在不改变原始列表的情况下创建一个没有给定元素的新列表。一种方法是使用列表推导式:


我假设您的意思是想要创建一个没有给定元素的新列表,而不是更改原始列表。一种方法是使用列表推导式:
m = ['a', 'b', 'c']
n = [x for x in m if x != 'a']

n现在是m的一个副本,但没有'a'元素。

当然还有另一种方式,就是先复制列表。

m = ['a', 'b', 'c']
n = m[:]
n.remove('a')

如果按索引删除一个值,那么这将更加简单。

n = m[:index] + m[index+1:]

4
在这个特定的例子中,我认为值得一提的是,如果您想要一个列表的副本,但不包括第0个元素,您可以使用m[1:]进行切片。 - kylieCatt
2
对,但我认为问题是希望按值而不是索引删除元素。不过,你说得对! - Krumelur
只有在确定它是列表中第一个不想要的元素时才有用,但我认为将来的读者了解列表切片如何工作会很有用。 - kylieCatt
3
我想补充一点,如果在列表中某个值不是唯一的,第一种方法和第二种方法会有不同的行为。第一种方法会删除所有出现的该值,而第二种方法只会删除第一次出现的。 - user12205

16
使用内置函数:filter,有一种简单的方法可以做到这一点。以下是一个示例:
a = [1, 2, 3, 4]
b = filter(lambda x: x != 3, a)

这太棒了。我点赞了。我简直不敢相信我在循环中运行list.pop()来实现这个。我的索引混乱了。 - Joker
过滤器方法不起作用。remove只会移除一个元素,而使用过滤器的方法会移除所有与给定值相等的元素。如果列表是[1,1,1,1,1,1,1,1,1,2],那么remove(x,1)将得到[1,1,1,1,1,1,1,1,2],而使用过滤器的方法将得到[2] - undefined

8
如果顺序无关紧要,您可以使用set(此外,在集合中删除似乎很快):
list(set(m) - set(['a']))

这将从您的原始列表中删除重复元素


4

我们可以使用列表的内置copy()函数来完成此操作;但是,应该为复制赋一个新名称。

m = ['a','b','c']
m_copy=m.copy()
m_copy.remove('a')

print (m)

["a", "b", "c"]

print(m_copy)

["b", "c"]


2
我们可以不使用内置的remove函数,也不创建新的列表变量来完成它。
代码:
# List m
m = ['a', 'b', 'c']

# Updated list m, without creating new list variable
m = [x for x in m if x != a]

print(m)

输出

>>> ['b', 'c']

1

另一种列表推导的方法是使用numpy:

>>> import numpy
>>> a = [1, 2, 3, 4]
>>> list(numpy.remove(a, a.index(3)))
[1, 2, 4]

现在这只对我有用:numpy.delete(a, a.index(3)) - yuki

1

您可以使用列表推导式创建一个不包含指定元素的新列表。这样可以保留原始列表的值。

l = ['a', 'b', 'c']
[s for s in l if s != 'a']

0

这个问题很有用,因为有时候我会在整个脚本中使用一个列表,但是在某个特定的步骤中,我需要对列表元素的子集应用逻辑。在这种情况下,我发现使用同一个列表,只需排除该单独步骤所需的元素即可,而无需创建一个完全不同名称的新列表。你可以使用以下任一方法:

  1. 列表推导式:假设你有 l=['a','b','c'] 要排除 b,你可以使用 [x for x in l if x!='b']
  2. 集合 [仅当顺序不重要时]:list(set(l) - set(['b'])),请注意,在此处将 'b' 作为列表 ['b'] 传递

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接