01/10/2018, 17:15
Sao chương trình chỉ remove 4 chữ None thôi vậy ạ?
def compact(array):
for i in array:
if None in array:
array.remove(None)
return(array)
print(compact([None, None, None, None, None, None, None, None]))
Bài liên quan
Tại lần lặp đầu, index của i = 0, index của None thứ nhất cũng = 0, i nhận giá trị là None thứ nhất, sau đó remove(None) xóa đi None thứ nhất, None thứ 2 lúc này index từ 1 giảm xuống 0 để lắp chỗ trống bị xóa của None thứ nhất, rồi None thứ 3, None thứ 4,… cũng thụt lùi về trước tương tự, thế là độ dài array bị giảm đi 1.
Tại lần lặp thứ 2, vấn đề bắt đầu từ đây, thay vì tiếp tục kiểm tra None thứ 2 (index = 0) thì i lại tăng thêm 1 (0 + 1=1) và nhận giá trị của None thứ 3 (cũng có index = 1), sau đó xóa đi None 3 làm None 4, 5, 6,… cũng thụt lùi về như bước 1, rồi giảm độ dài của array đi 1.
Thế nên cuối cùng vòng lặp chỉ chạy số lần bằng với độ dài array lúc đầu chia 2 vì độ dài array bị giảm ở mỗi bước lặp, như trong ví dụ thì vòng lặp dừng tại lần thứ 4 (vì index i = 3, cũng chính bằng len(array)-1), một số None bị bỏ qua như None thứ 2. Sr vì có thể mình giải thích hơi khó hiểu
Bất kì ngôn ngữ nào cũng có thể “dính” vào tình trạng dùng
for
để xóa phần tử nhưng không được kết quả mong đợi.Nên chú ý đừng bao giờ dùng
for
để xóa phần tử của mảng, mà hãy dùngwhile
.Mình từng bị rồi
Bản chất của for … in trong python là dùng 1 iterator
Trong iterator có sử dụng 1 it_index là chỉ số của
list
Sau mỗi vòng for it_index sẽ tăng lên 1 đơn vị là dừng lại khi >= len(list)
Để dễ giải thích mình dùng 1 mảng tương tự x = [0, 1, 2, 3, 4, 5, 6, 7]
it_index =0 -> i=0, it_index++, x.remove(i) => x=[1,2,3,4,5,6,7]
it_index =1 -> i=2, it_index++, x.remove(i) => x=[1,3,4,5,6,7]
it_index =2 -> i=4, it_index++, x.remove(i) => x=[1,3,5,6,7]
it_index =3 -> i=6, it_index++, x.remove(i) => x=[1,3,5,7]
Sau vòng lặp này it_index == len(x) nên vòng for dừng lại