Xóa các phần tử danh sách tại chỗ là có thể, nhưng không phải bằng cách chuyển tiếp qua danh sách. Mã của bạn chỉ đơn giản là không hoạt động - khi danh sách co lại, bạn có thể bỏ qua phần tử kiểm tra. Bạn cần phải lùi lại, để phần co lại phía sau bạn, với mã khá kinh khủng. Trước khi tôi cho bạn thấy điều đó, có một số cân nhắc sơ bộ:
Trước tiên, rác thải được đưa vào danh sách như thế nào? Phòng bệnh hơn chữa bệnh.
Thứ hai, số lượng phần tử trong danh sách và phần trăm nào có thể cần xóa? Tỷ lệ phần trăm càng cao thì khả năng tạo danh sách mới càng lớn.
OK, nếu bạn vẫn muốn làm điều đó tại chỗ, chiêm nghiệm này:
def list_cleanup_fail(alist, is_bad):
i = 0
for element in alist:
print "i=%d alist=%r alist[i]=%d element=%d" % (i, alist, alist[i], element)
if is_bad(element):
del alist[i]
i += 1
def list_cleanup_ok(alist, is_bad):
for i in xrange(len(alist) - 1, -1, -1):
print "i=%d alist=%r alist[i]=%d" % (i, alist, alist[i])
if is_bad(alist[i]):
del alist[i]
def is_not_mult_of_3(x):
return x % 3 != 0
for func in (list_cleanup_fail, list_cleanup_ok):
print
print func.__name__
mylist = range(11)
func(mylist, is_not_mult_of_3)
print "result", mylist
và đây là kết quả:
list_cleanup_fail
i=0 alist=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] alist[i]=0 element=0
i=1 alist=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] alist[i]=1 element=1
i=2 alist=[0, 2, 3, 4, 5, 6, 7, 8, 9, 10] alist[i]=3 element=3
i=3 alist=[0, 2, 3, 4, 5, 6, 7, 8, 9, 10] alist[i]=4 element=4
i=4 alist=[0, 2, 3, 5, 6, 7, 8, 9, 10] alist[i]=6 element=6
i=5 alist=[0, 2, 3, 5, 6, 7, 8, 9, 10] alist[i]=7 element=7
i=6 alist=[0, 2, 3, 5, 6, 8, 9, 10] alist[i]=9 element=9
i=7 alist=[0, 2, 3, 5, 6, 8, 9, 10] alist[i]=10 element=10
result [0, 2, 3, 5, 6, 8, 9]
list_cleanup_ok
i=10 alist=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] alist[i]=10
i=9 alist=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] alist[i]=9
i=8 alist=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] alist[i]=8
i=7 alist=[0, 1, 2, 3, 4, 5, 6, 7, 9] alist[i]=7
i=6 alist=[0, 1, 2, 3, 4, 5, 6, 9] alist[i]=6
i=5 alist=[0, 1, 2, 3, 4, 5, 6, 9] alist[i]=5
i=4 alist=[0, 1, 2, 3, 4, 6, 9] alist[i]=4
i=3 alist=[0, 1, 2, 3, 6, 9] alist[i]=3
i=2 alist=[0, 1, 2, 3, 6, 9] alist[i]=2
i=1 alist=[0, 1, 3, 6, 9] alist[i]=1
i=0 alist=[0, 3, 6, 9] alist[i]=0
result [0, 3, 6, 9]
Tôi nghĩ rằng bạn sẽ thấy rằng dòng suy nghĩ này gặp nhiều rắc rối hơn đáng giá. Chỉ cần sao chép danh sách, sửa đổi và trả lại bản sửa đổi. Sửa đổi một danh sách tại chỗ trong khi lặp nó chỉ là yêu cầu cho đau đầu. – jathanism
'del' là một câu lệnh, không phải là một hàm. Không quấn đối số của nó trong dấu ngoặc đơn. – jemfinch
Kích thước của đối tượng "trong danh sách" không liên quan vì Python không lưu trữ đối tượng trong danh sách; nó lưu trữ một tham chiếu đến đối tượng.Do đó, các vấn đề về hiệu suất có liên quan đến độ dài của danh sách và thuật toán được sử dụng để hoạt động trên danh sách chứ không phải là kích thước của các đối tượng được đề cập đến. – Nathan