问题:如何使用python从数组中删除特定元素
我想写一些东西从数组中删除一个特定的元素。我知道我必须for
遍历数组以查找与内容匹配的元素。
假设我有一组电子邮件,并且想摆脱与某些电子邮件字符串匹配的元素。
我实际上想使用for循环结构,因为我还需要对其他数组使用相同的索引。
这是我的代码:
for index, item in emails:
if emails[index] == 'something@something.com':
emails.pop(index)
otherarray.pop(index)
I want to write something that removes a specific element from an array. I know that I have to for
loop through the array to find the element that matches the content.
Let’s say that I have an array of emails and I want to get rid of the element that matches some email string.
I’d actually like to use the for loop structure because I need to use the same index for other arrays as well.
Here is the code that I have:
for index, item in emails:
if emails[index] == 'something@something.com':
emails.pop(index)
otherarray.pop(index)
回答 0
您不需要迭代数组。只是:
>>> 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]
You don’t need to iterate the array. Just:
>>> x = ['ala@ala.com', 'bala@bala.com']
>>> x
['ala@ala.com', 'bala@bala.com']
>>> x.remove('ala@ala.com')
>>> x
['bala@bala.com']
This will remove the first occurence that matches the string.
EDIT: After your edit, you still don’t need to iterate over. Just do:
index = initial_list.index(item1)
del initial_list[index]
del other_list[index]
回答 1
使用filter()
and lambda
将提供一种简洁的方法来删除不需要的值:
newEmails = list(filter(lambda x : x != 'something@something.com', emails))
这不会修改电子邮件。它创建新列表newEmails,其中仅包含匿名函数为其返回True的元素。
Using filter()
and lambda
would provide a neat and terse method of removing unwanted values:
newEmails = list(filter(lambda x : x != 'something@something.com', emails))
This does not modify emails. It creates the new list newEmails containing only elements for which the anonymous function returned True.
回答 2
如果需要在for循环中使用索引,则for循环不正确:
for index, item in enumerate(emails):
# whatever (but you can't remove element while iterating)
对于您而言,Bogdan解决方案是可以的,但是您选择的数据结构不是很好。必须用来自一个的数据与来自另一个的数据以相同的索引来维护这两个列表是笨拙的。
最好使用连音(电子邮件,其他数据)列表,或者以电子邮件为键的字典。
Your for loop is not right, if you need the index in the for loop use:
for index, item in enumerate(emails):
# whatever (but you can't remove element while iterating)
In your case, Bogdan solution is ok, but your data structure choice is not so good. Having to maintain these two lists with data from one related to data from the other at same index is clumsy.
A list of tupple (email, otherdata) may be better, or a dict with email as key.
回答 3
做到这一点的理智方法是使用zip()
和List Comprehension / Generator表达式:
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()
,这会为您提供列表,而不是数组。不一样的东西。
The sane way to do this is to use zip()
and a List Comprehension / Generator Expression:
filtered = (
(email, other)
for email, other in zip(emails, other_list)
if email == 'something@something.com')
new_emails, new_other_list = zip(*filtered)
Also, if your’e not using array.array()
or numpy.array()
, then most likely you are using []
or list()
, which give you Lists, not Arrays. Not the same thing.
回答 4
有一个替代解决方案,该问题还处理重复的匹配项。
我们先从相同长度的2所列出:emails
,otherarray
。目的是从两个列表中的每个索引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']
There is an alternative solution to this problem which also deals with duplicate matches.
We start with 2 lists of equal length: emails
, otherarray
. The objective is to remove items from both lists for each index i
where emails[i] == 'something@something.com'
.
This can be achieved using a list comprehension and then splitting via 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']