如何使用Python从数组中删除特定元素

155

我想写一个功能,可以从数组中删除特定的元素。我知道我必须使用 for 循环遍历数组来查找与内容匹配的元素。

假设我有一个电子邮件的数组,并且我想要移除与某些电子邮件字符串匹配的元素。

我实际上想使用 for 循环结构,因为我需要使用同一个索引来处理其他数组。

这是我的代码:

for index, item in emails:
    if emails[index] == 'something@something.com':
         emails.pop(index)
         otherarray.pop(index)

7
你是否在寻找list.remove(x) - Jacob
不太对。我想使用for循环,这样我就可以重复使用索引。 - locoboy
4
在迭代列表时不应该改变它。 - Jacob
6
请看这个链接:不要在迭代过程中修改列表 - Jacob
您还可以以相反的顺序迭代列表。然后,删除的元素索引将指向最后一个检查的元素,但是当索引递减时,它将指向您希望检查的下一个元素。我不认为支持这种行为,但在迄今为止的版本中运行得足够好,因此非常有用。 - MrWonderful
显示剩余2条评论
7个回答

227

无需迭代数组,只需:

>>> x = ['ala@ala.com', 'bala@bala.com']
>>> x
['ala@ala.com', 'bala@bala.com']
>>> x.remove('ala@ala.com')
>>> x
['bala@bala.com']
这将删除与字符串匹配的第一个实例。
编辑:在您的编辑之后,仍然不需要进行迭代。只需执行:
index = initial_list.index(item1)
del initial_list[index]
del other_list[index]

1
我想使用for循环来重复使用相同的索引。 - locoboy
修改了我的回答。仍然不需要循环。 - Bogdan
2
你首先如何检查initial_list中是否存在该项?可能存在不存在的情况,因此您不必将其删除。 - locoboy
1
@locoboy 有两种选择。第一种是测试 item in initial_list,第二种是用 try:代码: except ValueError 块包裹 remove 操作。 - Hettomei

21

使用filter()lambda可以提供一种简洁明了的方法来删除不需要的值:

newEmails = list(filter(lambda x : x != 'something@something.com', emails))

这不修改电子邮件。它创建了一个新列表newEmails,其中仅包含匿名函数返回True的元素。


5

你的for循环不正确,如果需要在for循环中使用索引,请使用以下方法:

for index, item in enumerate(emails):
    # whatever (but you can't remove element while iterating)

在您的情况下,Bogdan的解决方案是可以的,但您选择的数据结构并不好。需要在两个列表中维护相关数据,且这些数据需要在相同的索引处,这种方式很笨拙。
使用元组列表(电子邮件,其他数据)可能更好,或者使用以电子邮件为键的字典。

4

做到这一点的正确方法是使用zip()和列表推导式/生成器表达式:

filtered = (
    (email, other) 
        for email, other in zip(emails, other_list) 
            if email == 'something@something.com')

new_emails, new_other_list = zip(*filtered)

此外,如果您没有使用 array.array()numpy.array(),那么很可能您正在使用 []list(),这些将给您提供列表(Lists),而不是数组(Arrays)。它们并不相同。

2
不确定这与@Bogdan的答案相比如何“合理”,后者要干净得多。 - Jordan Lapp
感谢指出数组和列表不同的地方。在2.7中,所选答案对数组无效。 - EL_DON

3

这个问题有一种替代方案,也可以处理重复匹配。

我们从长度相等的2个列表开始:emailsotherarray。目标是在每个索引 i 处从两个列表中删除项,其中 emails[i] == 'something@something.com'

可以使用列表推导式并通过 zip 进行拆分来实现此目的:

emails = ['abc@def.com', 'something@something.com', 'ghi@jkl.com']
otherarray = ['some', 'other', 'details']

from operator import itemgetter

res = [(i, j) for i, j in zip(emails, otherarray) if i!= 'something@something.com']
emails, otherarray = map(list, map(itemgetter(0, 1), zip(*res)))

print(emails)      # ['abc@def.com', 'ghi@jkl.com']
print(otherarray)  # ['some', 'details']

3

如果想要删除数组中的索引:

使用 array_name.pop(index_no.)

例如:

>>> arr = [1,2,3,4]
>>> arr.pop(2)
>>>arr
[1,2,4]

如果您想从数组中删除特定的字符串/元素,则

>>> arr1 = ['python3.6' , 'python2' ,'python3']
>>> arr1.remove('python2')
>>> arr1
['python3.6','python3']

0
使用numpy中的setdiff1d()函数从数组中删除所需的项。您可以传递一个要从给定数组中删除的元素数组。
import numpy as np
test=np.array([1,2,3,4,5,45,65,34])
elements_to_remove=np.array([2,65])
t=np.setdiff1d(test,elements_to_remove)
print(test)
print(t)

输出的样子是这样的:
[ 1  2  3  4  5 45 65 34]
[ 1  3  4  5 34 45]

原始数组中已经移除了2和65。

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