Eine In-Place-Methode
Diese Methode ist quadratisch, da wir für jedes Element der Liste eine lineare Suche in der Liste haben (dazu müssen wir die Kosten für die Neuanordnung der Liste aufgrund der hinzufügen del
s ).
Das heißt, es ist möglich, an Ort und Stelle zu arbeiten, wenn wir am Ende der Liste beginnen und zum Ursprung gehen und jeden Begriff entfernen, der in der Unterliste links davon vorhanden ist
Diese Idee im Code ist einfach
for i in range(len(l)-1,0,-1):
if l[i] in l[:i]: del l[i]
Ein einfacher Test der Implementierung
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
könnte sich zwischen den Iterationen geändert haben, und die Laufzeit ist nicht intelligent genug, um dies auszuschließen. Um auf Nummer sicher zu gehen, muss das Objekt jedes Mal überprüft werden. - Wenn Sie sich den Bytecode mit ansehendis.dis(f)
, können Sie sehen, dass er bei jeder IterationLOAD_ATTR
für dasadd
Mitglied ausgeführt wird. ideone.com/tz1Tll