Cần giải thích cách hoạt động của đoạn code

lst=[2,1,4,7,9,13,15,25,15,13,2,4,0,12,6,8,12,14]
for i in lst:
    print(i)
    if i % 2 == 0:
        lst.remove(i)
print(lst)

kết quả hiện thị là 2 4 9 13 15 25 15 13 2 0 6 12 tại sao nó lại hiện thị như thế này ạ đáng nhẽ nó phải chạy hết mảng lst đúng không ạ
[1, 7, 9, 13, 15, 25, 15, 13, 4, 8, 12, 14]

https://repl.it/repls/CompetentBlushingRoot

À ý là hỏi tại sao mảng vẫn còn 8, 12 với 14 các thứ… oops

7 Likes

ý của em muốn hỏi là tại sao khi dùng lst.remove(i)
thì câu lệnh print(i) lại ra kết quả 2 4 9 13 15 25 15 13 2 0 6 12
mà không phải là 2,1,4,7,9,13,15,25,15,13,2,4,0,12,6,8,12,14 bác ạ

(oops) Khi remove (mất 1 obj thôi) thì dãy lùi 1 ô để lấp, nhưng số (counter) vẫn nhảy thành ra còn thừa mấy số chẵn.

Cái này nên dùng comprehension.

6 Likes

nhưng tại sao câu lệnh:

if i % 2 == 0:
    lst.remove(i)

tức là xoá đi phần tử chẵn rồi sao kết quả lại vẫn còn phần tử cả chẵn cả lẻ ạ

1 Like

Một trong những kinh nghiệm mình học được khi học python là không nên thêm/bớt item của một list khi mình đang chạy (loop) list đó, vì rất khó kiểm soát được hành vi của việc thêm/bớt item đó.

nên tạo list khác/list tạm để xử lý

6 Likes

Hoặc dùng while thôi :slight_smile:

5 Likes

Ví dụ thế này cho bạn dễ hiểu:

lst=[2,1,4,7,9,13,15,25,15,13,2,4,0,12,6,8,12,14]


for i in lst:
    print('Số {} có index là {}'.format(str(i), lst.index(i)))

    if i % 2 == 0:
        lst.remove(i)
print(lst)

sẽ ra output là

Số 2 có index là 0
Số 4 có index là 1
Số 9 có index là 2
Số 13 có index là 3
Số 15 có index là 4
Số 25 có index là 5
Số 15 có index là 4
Số 13 có index là 3
Số 2 có index là 8
Số 0 có index là 9
Số 6 có index là 10
Số 12 có index là 9
[1, 7, 9, 13, 15, 25, 15, 13, 4, 8, 12, 14]
[Finished in 0.1s]

Items được in ra không đủ, và index thì rất lộn xộn, đó là do số lượng và thứ tự của item trong list bị thay đổi khi đang loop. Bạn không hiểu là vì cái chỗ đây

(Do list có item bị duplicate, nên cái index in ra không đúng, nhưng ví dụ vẫn đủ để thể hiện cái sự lộn xộn khi bị thêm bớt item nên mình không sử lại. Sorry)

7 Likes

Để cho dễ theo dõi :smiley:

def modify_list(list):
   counter = 0
   for i in list:
      print(f"Số {i} có index là {counter}")
      if i % 2 == 0: list.remove(i) 
      counter += 1 # tường minh

Khi counter = 1: Giữa số 4 và số 9 là số 7, và 7 là số lẻ. Do 7 dồn vào thế chỗ 4 nên lần sau vòng lặp qua slot số hai là 9.

Ngoài ra for in hash nếu thêm xóa sẽ văng exception.

9 Likes

Cảm ơn mọi người mình đã hiểu rồi
Xin chân thành cảm ơn

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?