Jag behöver skriva ett program som kontrollerar om en lista har några dubbletter och om så är fallet tar det bort dem och returnerar en ny lista med de objekt som inte var duplicerade eller borttagna. Detta är vad jag har men om jag ska vara ärlig vet jag inte vad jag ska göra.
def remove_duplicates():
t = ['a', 'b', 'c', 'd']
t2 = ['a', 'c', 'd']
for t in t2:
t.append(t.remove())
return t
Det vanligaste sättet att få en unik samling objekt är att använda en [set
] (http://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset). Sets är osordnade samlingar av distinkta objekt. För att skapa en uppsättning från en iterabel kan du helt enkelt skicka den till den inbyggda funktionen set()
. Om du senare behöver en riktig lista igen kan du på samma sätt skicka mängden till funktionen list()
.
Följande exempel bör täcka vad du än försöker göra:
>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> list(set(t))
[1, 2, 3, 5, 6, 7, 8]
>>> s = [1, 2, 3]
>>> list(set(t) - set(s))
[8, 5, 6, 7]
Som du kan se av resultatet i exemplet, bevaras inte den ursprungliga ordningen. Som nämnts ovan är uppsättningar i sig själva oordnade samlingar, så ordningen går förlorad. När en uppsättning konverteras tillbaka till en lista skapas en godtycklig ordning.
Om ordningen är viktig för dig måste du använda en annan mekanism. En mycket vanlig lösning för detta är att förlita sig på [OrderedDict
] (https://docs.python.org/3/library/collections.html#collections.OrderedDict) för att behålla nycklarnas ordning under insättning:
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
Från och med Python 3.7 garanteras det inbyggda lexikonet att det också behåller ordningen vid insättning, så du kan också använda det direkt om du har Python 3.7 eller senare (eller CPython 3.6):
>>> list(dict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
Observera att det här har en överlappning av att först skapa en ordbok och sedan skapa en lista från den. Om du faktiskt inte behöver bevara ordningen är det bättre att använda en uppsättning. Se denna fråga för mer information och alternativa sätt att bevara ordningen när du tar bort dubbletter.
Observera slutligen att både set
och OrderedDict
/dict
-lösningarna kräver att dina objekt är hashable. Detta innebär vanligtvis att de måste vara oföränderliga. Om du måste hantera objekt som inte är hashable (t.ex. listobjekt) måste du använda ett långsamt tillvägagångssätt där du i princip måste jämföra varje objekt med varje annat objekt i en inbäddad slinga.
Det är en enkel linje: list(set(source_list))
räcker.
En set
är något som omöjligt kan ha dubbletter.
Uppdatering: en ordningssäkrad metod är två rader:
from collections import OrderedDict
OrderedDict((x, True) for x in source_list).keys()
Här använder vi oss av det faktum att OrderedDict
kommer ihåg nycklarnas insättningsordning och inte ändrar den när ett värde på en viss nyckel uppdateras. Vi infogar True
som värden, men vi skulle kunna infoga vad som helst, värdena används bara inte. (set
fungerar också mycket som en dict
med ignorerade värden.)