Ta bort och extrahera dubbla element från en lista (array) i Python

Företag

I det här avsnittet beskrivs hur man skapar en ny lista i Python genom att ta bort eller extrahera dubbla element från en lista (array).

Här beskrivs följande detaljer.

  • Ta bort dubbla element och skapa nya listor
    • Behåll inte ordningen i den ursprungliga förteckningen.:set()
    • Behåller ordningen i den ursprungliga förteckningen.: dict.fromkeys(),sorted()
    • Tvådimensionell matris (lista av listor)
  • Extrahera dubbla element och skapa en ny lista
    • Behåll inte ordningen i den ursprungliga förteckningen.
    • Behåller ordningen i den ursprungliga förteckningen.
    • Tvådimensionell matris (lista av listor)

Samma koncept kan tillämpas på tupler i stället för listor.

Se följande artikel för mer information om

  • Om du vill avgöra om en lista eller tupel har dubbla element
  • Om du vill extrahera element som är vanliga eller inte vanliga bland flera listor i stället för en enskild lista

Observera att listor kan lagra olika typer av data och skiljer sig strikt från matriser. Om du vill hantera matriser i processer som kräver minnesstorlek och minnesadresser eller numerisk behandling av stora data, använd array (standardbiblioteket) eller NumPy.

Ta bort dubbla element och skapa nya listor

Behåll inte ordningen i den ursprungliga förteckningen.: set()

Om det inte finns något behov av att bevara ordningen i den ursprungliga listan kan du använda set(), som genererar en uppsättning av typen set.

Uppsättningstypen är en datatyp som inte har några dubbla element. När en lista eller annan datatyp skickas till set() ignoreras dubbla värden och ett objekt av typen set returneras där endast unika värden är element.

Om du vill göra det till en tupel använder du tuple().

l = [3, 3, 2, 1, 5, 1, 4, 2, 3]

print(set(l))
# {1, 2, 3, 4, 5}

print(list(set(l)))
# [1, 2, 3, 4, 5]

Naturligtvis kan den också lämnas som den är. I följande artikel finns mer information om den inställda typen set.

Behåller ordningen i den ursprungliga förteckningen.: dict.fromkeys(),sorted()

Om du vill behålla ordningen i den ursprungliga listan använder du klassmetoden fromkeys() för ordbokstypen eller den inbyggda funktionen sorted().

dict.fromkeys() skapar ett nytt ordboksobjekt vars nycklar är de listor, tupler etc. som anges i argumenten. Om det andra argumentet utelämnas är värdet None.

Eftersom ordboksnycklar inte har dubbla element ignoreras dubbla värden på samma sätt som i set(). Dessutom kan ett ordboksobjekt skickas som ett argument till list() för att få en lista vars element är ordboksnycklar.

print(dict.fromkeys(l))
# {3: None, 2: None, 1: None, 5: None, 4: None}

print(list(dict.fromkeys(l)))
# [3, 2, 1, 5, 4]

Sedan Python 3.7 (CPython är 3.6) har det garanterats att dict.fromkeys() bevarar ordningen på argumentsekvensen. Tidigare versioner använder den inbyggda funktionen sorted() på följande sätt.

Ange listtupelmetoden index() för argumentet key för sorted, som returnerar en sorterad lista med element.

index() är en metod som returnerar indexet för värdet (numret på elementet i listan), som kan anges som nyckel i sorted() för att sortera listan baserat på ordningen i den ursprungliga listan. Argumentet key specificeras som ett uppringbart (callable) objekt, så skriv inte ().

print(sorted(set(l), key=l.index))
# [3, 2, 1, 5, 4]

Tvådimensionell matris (lista av listor)

För tvådimensionella matriser (listor av listor) resulterar metoden som använder set() eller dict.fromkeys() i ett TypeError.

l_2d = [[1, 1], [0, 1], [0, 1], [0, 0], [1, 0], [1, 1], [1, 1]]

# l_2d_unique = list(set(l_2d))
# TypeError: unhashable type: 'list'

# l_2d_unique_order = dict.fromkeys(l_2d)
# TypeError: unhashable type: 'list'

Detta beror på att icke-hashbara objekt som listor inte kan vara element av typen set eller nycklar av typen dict.

Definiera följande funktioner Ordningen i den ursprungliga listan bevaras och fungerar för endimensionella listor och tupler.

def get_unique_list(seq):
    seen = []
    return [x for x in seq if x not in seen and not seen.append(x)]

print(get_unique_list(l_2d))
# [[1, 1], [0, 1], [0, 0], [1, 0]]

print(get_unique_list(l))
# [3, 2, 1, 5, 4]

Notering för listförståelse används.

Här använder vi följande

  • Om X i ”X och Y” är falskt i kortslutningsutvärderingen av och-operatorn, utvärderas inte Y (utförs inte).
  • Metoden append() returnerar inget.

Om elementen i den ursprungliga listan seq inte finns i seen utvärderas then och after.
seen.append(x) utförs och elementet läggs till i seen.
Eftersom append()-metoden returnerar None och None är False, blir inte seen.append(x) värderad till True.
Det villkorliga uttrycket i listförståelsen blir sant och läggs till som ett element i den slutliga genererade listan.

Om elementen i den ursprungliga listan seq finns i seen är x som inte finns i seen False, och det villkorliga uttrycket för listförståelseuttrycket är False.
De läggs därför inte till i den slutliga genererade förteckningen.

En annan metod är att ställa in argumentaxeln i NumPys funktion np.unique(), även om resultatet kommer att sorteras.

Extrahera dubbla element och skapa en ny lista

Behåll inte ordningen i den ursprungliga förteckningen.

Om du bara vill ta ut dubbletter från den ursprungliga listan använder du collections.Counter().
Återger en collections.Counter (en underklass till dictionary) med elementen som nycklar och antalet element som värden.

import collections

l = [3, 3, 2, 1, 5, 1, 4, 2, 3]

print(collections.Counter(l))
# Counter({3: 3, 2: 2, 1: 2, 5: 1, 4: 1})

Eftersom det är en underklass till dictionary kan items() användas för att hämta nycklar och värden. Det räcker att hämta nycklar vars antal är två eller fler.

print([k for k, v in collections.Counter(l).items() if v > 1])
# [3, 2, 1]

Behåller ordningen i den ursprungliga förteckningen.

Som framgår av exemplet ovan behåller nycklarna i collections.Counter sedan Python 3.7 ordningen i den ursprungliga listan och så vidare.

I tidigare versioner räcker det att sortera med sorted() och att ta bort dubbla element.

print(sorted([k for k, v in collections.Counter(l).items() if v > 1], key=l.index))
# [3, 2, 1]

Om du vill ta bort dubbletter som de är, lämna helt enkelt element från den ursprungliga listan med ett nummer på två eller fler. Ordningen bevaras också.

cc = collections.Counter(l)
print([x for x in l if cc[x] > 1])
# [3, 3, 2, 1, 1, 2, 3]

Tvådimensionell matris (lista av listor)

För tvådimensionella matriser (listor av listor) är följande funktioner möjliga när ordningen i den ursprungliga listan inte behålls respektive när den behålls. Det fungerar även för endimensionella listor och tupler.

l_2d = [[1, 1], [0, 1], [0, 1], [0, 0], [1, 0], [1, 1], [1, 1]]
def get_duplicate_list(seq):
    seen = []
    return [x for x in seq if not seen.append(x) and seen.count(x) == 2]

def get_duplicate_list_order(seq):
    seen = []
    return [x for x in seq if seq.count(x) > 1 and not seen.append(x) and seen.count(x) == 1]

print(get_duplicate_list(l_2d))
# [[0, 1], [1, 1]]

print(get_duplicate_list_order(l_2d))
# [[1, 1], [0, 1]]

print(get_duplicate_list(l))
# [3, 1, 2]

print(get_duplicate_list_order(l))
# [3, 2, 1]

Om du vill extrahera med dubbletter lämnar du element från den ursprungliga listan med ett antal på två eller fler.

print([x for x in l_2d if l_2d.count(x) > 1])
# [[1, 1], [0, 1], [0, 1], [1, 1], [1, 1]]

Observera att eftersom beräkningskomplexiteten för count() är O(n) är den funktion som visas ovan och som upprepade gånger utför count() mycket ineffektiv. Det kan finnas ett smartare sätt.

Counter är en underklass till dictionary, så om du skickar en lista eller tupel vars element är listor eller andra icke-hashbara objekt till collections.Counter() kommer ett fel att uppstå och du kommer inte att kunna använda den.

# print(collections.Counter(l_2d))
# TypeError: unhashable type: 'list'