2009-08-30 40 views
10

Trong Java tôi có thể làm bằng cách sử dụng một Iterator và sau đó sử dụng phương pháp .remove() của iterator để loại bỏ các yếu tố cuối cùng được trả về bởi các iterator, như thế này:Hủy bỏ các yếu tố như bạn đi qua một danh sách bằng Python

import java.util.*; 

public class ConcurrentMod { 
    public static void main(String[] args) { 
     List<String> colors = new ArrayList<String>(Arrays.asList("red", "green", "blue", "purple")); 
     for (Iterator<String> it = colors.iterator(); it.hasNext();) { 
      String color = it.next(); 
      System.out.println(color); 
      if (color.equals("green")) 
       it.remove(); 
     } 
     System.out.println("At the end, colors = " + colors); 
    } 
} 

/* Outputs: 
red 
green 
blue 
purple 
At the end, colors = [red, blue, purple] 
*/ 

Làm thế nào tôi sẽ làm điều này trong Python? Tôi không thể sửa đổi danh sách trong khi tôi lặp lại nó trong vòng lặp for vì nó khiến nội dung bị bỏ qua (xem here). Và dường như không tương đương với giao diện Iterator của Java.

+0

tôi tự hỏi nếu sử dụng một iterator đảo ngược có thể là một giải pháp. Bất kỳ suy nghĩ về điều này? Nó sẽ tốt hơn là tạo một bản sao của một danh sách. –

+0

http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating-in-python Nó được yêu cầu rất nhiều ... –

Trả lời

18

lặp trên một bản sao của danh sách:

for c in colors[:]: 
    if c == 'green': 
     colors.remove(c) 
+0

Tại sao màu [:] thay vì màu? – hughdbrown

+4

'colors [:]' là một bản sao (một cách kỳ lạ nhưng, thở dài, thành ngữ để đánh vần 'danh sách (màu)') để nó không bị ảnh hưởng bởi các cuộc gọi '.remove'. –

+1

Lý do duy nhất để gọi nó thành ngữ hơn là vì tài liệu mô-đun sao chép stdlib tham chiếu đến nó. Mặc dù vậy, tôi vẫn sẽ sử dụng danh sách (danh sách khác) cho các bản sao (hoặc có thể copy.copy (thứ khác)) –

26

cách tiếp cận tốt nhất trong Python là để tạo ra một danh sách mới, lý tưởng trong một listcomp, thiết lập nó như là [:] của cái cũ, ví dụ:

colors[:] = [c for c in colors if c != 'green'] 

KHÔNG colors = như một số câu trả lời có thể đề nghị - mà chỉ có rebinds tên và cuối cùng sẽ để lại một số tài liệu tham khảo cho "cơ thể" lủng lẳng cũ; colors[:] = là MUCH tốt hơn trên tất cả các số ;-).

+1

Danh sách hiểu là sự lựa chọn tốt nhất. – hughdbrown

+0

hoặc colors = list (c cho c màu nếu c! = 'Green') – dugres

+0

@dugres: không hoàn toàn: colors = list (...) hiện rebind. Alex nhấn mạnh vào ý tưởng rằng tốt hơn là đừng để những danh sách vô dụng lơ lửng trong ký ức. – EOL

4

Bạn có thể sử dụng chức năng lọc:

>>> colors=['red', 'green', 'blue', 'purple'] 
>>> filter(lambda color: color != 'green', colors) 
['red', 'blue', 'purple'] 
>>> 
0

hoặc bạn cũng có thể làm như thế này

>>> colors = ['red', 'green', 'blue', 'purple'] 
>>> if colors.__contains__('green'): 
...  colors.remove('green') 
+3

Không có lợi thế nào khi sử dụng '.__ chứa __()' trên ''xanh' trong màu sắc ' –

+1

Plus, colors.remove() chỉ xóa * lần xuất hiện * đầu tiên thay vì tất cả các lần xuất hiện. – EOL

+2

Các giải pháp có thể được thực hiện để làm việc, thông qua: trong khi 'xanh' trong màu sắc: colors.remove ('xanh'). Tất nhiên, đây là O (n ** 2), trong khi các giải pháp tốt hơn là O (n). –

Các vấn đề liên quan