Cách xóa phần tử cụ thể khỏi một mảng bằng python


138

Tôi muốn viết một cái gì đó loại bỏ một yếu tố cụ thể từ một mảng. Tôi biết rằng tôi phải forlặp qua mảng để tìm phần tử phù hợp với nội dung.

Hãy nói rằng tôi có một loạt các email và tôi muốn loại bỏ yếu tố phù hợp với một số chuỗi email.

Tôi thực sự muốn sử dụng cấu trúc vòng lặp for vì tôi cũng cần sử dụng cùng một chỉ mục cho các mảng khác.

Đây là mã mà tôi có:

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

6
Bạn đang tìm kiếm list.remove(x)?
Jacob

không hẳn. tôi muốn sử dụng vòng lặp for để tôi có thể sử dụng lại chỉ mục
locoboy

4
Bạn không nên thay đổi danh sách trong khi lặp qua nó.
Jacob

Tại sao tôi không nên làm điều này? nó cũng không làm việc cho tôi
locoboy

Câu trả lời:


200

Bạn không cần phải lặp lại mảng. Chỉ:

>>> x = ['ala@ala.com', 'bala@bala.com']
>>> x
['ala@ala.com', 'bala@bala.com']
>>> x.remove('ala@ala.com')
>>> x
['bala@bala.com']

Điều này sẽ loại bỏ sự xuất hiện đầu tiên phù hợp với chuỗi.

EDIT: Sau khi chỉnh sửa, bạn vẫn không cần phải lặp đi lặp lại. Cứ làm đi:

index = initial_list.index(item1)
del initial_list[index]
del other_list[index]

1
xem ở trên tôi muốn sử dụng vòng lặp for để sử dụng lại cùng một chỉ mục
locoboy

Chỉnh sửa câu trả lời của tôi. Vẫn không cần vòng lặp.
Bogdan

1
Làm thế nào để bạn kiểm tra đầu tiên rằng mục tồn tại trong init_list? Có thể có trường hợp nó không tồn tại và bạn sẽ không phải xóa nó.
locoboy

17

Sử dụng filter()lambdasẽ cung cấp một phương pháp gọn gàng và ngắn gọn để loại bỏ các giá trị không mong muốn:

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

Điều này không sửa đổi email. Nó tạo danh sách mới newEmails chỉ chứa các phần tử mà hàm ẩn danh trả về True.


5

Vòng lặp for của bạn không đúng, nếu bạn cần chỉ mục trong vòng lặp for sử dụng:

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

Trong trường hợp của bạn, giải pháp Bogdan là ổn, nhưng lựa chọn cấu trúc dữ liệu của bạn không tốt lắm. Phải duy trì hai danh sách này với dữ liệu từ một liên quan đến dữ liệu từ cùng một chỉ mục là vụng về.

Một danh sách các tupple (email, otherdata) có thể tốt hơn hoặc một lệnh với email là khóa.


4

Cách lành mạnh để làm điều này là sử dụng zip()và Biểu thức hiểu / tạo biểu đồ:

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

new_emails, new_other_list = zip(*filtered)

Ngoài ra, nếu bạn không sử dụng array.array()hoặc numpy.array(), thì rất có thể bạn đang sử dụng []hoặc list(), cung cấp cho bạn Danh sách, không phải Mảng. Không giống nhau.


1
Không có gì chắc chắn làm thế nào điều này là "lành mạnh" so với câu trả lời của @ Bogdan, nó sạch sẽ hơn nhiều.
Jordan Lapp

Cảm ơn đã chỉ ra rằng các mảng không giống như danh sách. Câu trả lời được chọn không hoạt động trên mảng trong 2.7.
EL_DON

2

Có một giải pháp thay thế cho vấn đề này cũng liên quan đến các trận đấu trùng lặp.

Chúng tôi bắt đầu với 2 danh sách có độ dài bằng nhau: emails, otherarray. Mục tiêu là để xóa các mục từ danh sách cho mỗi chỉ số inơi emails[i] == 'something@something.com'.

Điều này có thể đạt được bằng cách sử dụng một sự hiểu biết danh sách và sau đó phân tách thông qua 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']
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.