Một phương pháp tại chỗ
Phương pháp này là bậc hai, bởi vì chúng tôi có một tra cứu tuyến tính vào danh sách cho mọi phần tử của danh sách (để chúng tôi phải thêm chi phí sắp xếp lại danh sách vì del
s).
Điều đó nói rằng, có thể hoạt động tại chỗ nếu chúng ta bắt đầu từ cuối danh sách và tiến tới nguồn gốc loại bỏ từng thuật ngữ có trong danh sách phụ ở bên trái
Ý tưởng này trong mã chỉ đơn giản là
for i in range(len(l)-1,0,-1):
if l[i] in l[:i]: del l[i]
Một thử nghiệm đơn giản về việc thực hiện
In [91]: from random import randint, seed
In [92]: seed('20080808') ; l = [randint(1,6) for _ in range(12)] # Beijing Olympics
In [93]: for i in range(len(l)-1,0,-1):
...: print(l)
...: print(i, l[i], l[:i], end='')
...: if l[i] in l[:i]:
...: print( ': remove', l[i])
...: del l[i]
...: else:
...: print()
...: print(l)
[6, 5, 1, 4, 6, 1, 6, 2, 2, 4, 5, 2]
11 2 [6, 5, 1, 4, 6, 1, 6, 2, 2, 4, 5]: remove 2
[6, 5, 1, 4, 6, 1, 6, 2, 2, 4, 5]
10 5 [6, 5, 1, 4, 6, 1, 6, 2, 2, 4]: remove 5
[6, 5, 1, 4, 6, 1, 6, 2, 2, 4]
9 4 [6, 5, 1, 4, 6, 1, 6, 2, 2]: remove 4
[6, 5, 1, 4, 6, 1, 6, 2, 2]
8 2 [6, 5, 1, 4, 6, 1, 6, 2]: remove 2
[6, 5, 1, 4, 6, 1, 6, 2]
7 2 [6, 5, 1, 4, 6, 1, 6]
[6, 5, 1, 4, 6, 1, 6, 2]
6 6 [6, 5, 1, 4, 6, 1]: remove 6
[6, 5, 1, 4, 6, 1, 2]
5 1 [6, 5, 1, 4, 6]: remove 1
[6, 5, 1, 4, 6, 2]
4 6 [6, 5, 1, 4]: remove 6
[6, 5, 1, 4, 2]
3 4 [6, 5, 1]
[6, 5, 1, 4, 2]
2 1 [6, 5]
[6, 5, 1, 4, 2]
1 5 [6]
[6, 5, 1, 4, 2]
In [94]:
seen.add
có thể đã thay đổi giữa các lần lặp và thời gian chạy không đủ thông minh để loại trừ điều đó. Để chơi an toàn, nó phải kiểm tra đối tượng mỗi lần. - Nếu bạn nhìn vào mã byte vớidis.dis(f)
, bạn có thể thấy rằng nó thực thiLOAD_ATTR
choadd
thành viên trên mỗi lần lặp. ideone.com/tz1Tll