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]))
Anh chàng Doggo viết 19:16 ngày 01/10/2018
def compact(array):
	i = 0
	while(i < len(array)):
		if array[i] == None:
			array.remove(array[i])
		else:
			i+=1
	return array
print(compact([None, None, None]))
Anh chàng Doggo viết 19:20 ngày 01/10/2018

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

Trương Tấn Phát viết 19:30 ngày 01/10/2018

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ùng while.

Mình từng bị rồi

def compact(array):
   while(None in array):
      array.remove(None)
   return(array)

print(compact([None, None, None, None, None, None, None, None]))
Gió viết 19:24 ngày 01/10/2018

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]

for i in x:
    x.remove(i)
  • vòng lặp 1:
    it_index =0 -> i=0, it_index++, x.remove(i) => x=[1,2,3,4,5,6,7]
  • vòng lặp 2:
    it_index =1 -> i=2, it_index++, x.remove(i) => x=[1,3,4,5,6,7]
  • vòng lặp 3:
    it_index =2 -> i=4, it_index++, x.remove(i) => x=[1,3,5,6,7]
  • vòng lặp 4:
    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
Bài liên quan
0