Odstranění a extrakce duplicitních prvků ze seznamu (pole) v jazyce Python

Podnikání

Tato část popisuje, jak v jazyce Python vytvořit nový seznam odstraněním nebo vyjmutím duplicitních prvků ze seznamu (pole).

Zde jsou popsány následující podrobnosti.

  • Odstranění duplicitních prvků a generování nových výpisů
    • Nezachovávejte pořadí původního seznamu.:set()
    • Zachovává pořadí původního seznamu: dict.fromkeys(),sorted()
    • Dvourozměrné pole (seznam seznamů)
  • Výběr duplicitních prvků a vytvoření nového seznamu
    • Nezachovávejte pořadí původního seznamu.
    • Zachovává pořadí původního seznamu
    • Dvourozměrné pole (seznam seznamů)

Stejný koncept lze použít i pro tuply namísto seznamů.

Viz následující článek

  • Pokud chcete zjistit, zda seznam nebo tuple obsahuje duplicitní prvky.
  • Pokud chcete extrahovat prvky, které jsou nebo nejsou společné pro více výpisů namísto jednoho výpisu.

Všimněte si, že seznamy mohou uchovávat různé typy dat a striktně se liší od polí. Pokud chcete s poli pracovat v procesech, které vyžadují velikost paměti a paměťové adresy nebo numerické zpracování velkých dat, použijte pole (standardní knihovna) nebo NumPy.

Odstranění duplicitních prvků a generování nových výpisů

Nezachovávejte pořadí původního seznamu.: set()

Pokud není třeba zachovat pořadí původního seznamu, použijte funkci set(), která vygeneruje množinu typu set.

Typ množiny je datový typ, který nemá duplicitní prvky. Pokud je funkci set() předán seznam nebo jiný datový typ, duplicitní hodnoty jsou ignorovány a je vrácen objekt typu set, jehož prvky jsou pouze jedinečné hodnoty.

Pokud z něj chcete vytvořit tuple, použijte funkci 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]

Samozřejmě ji lze také ponechat nastavenou. Více informací o typu set naleznete v následujícím článku.

Zachovává pořadí původního seznamu: dict.fromkeys(),sorted()

Pokud chcete zachovat pořadí původního seznamu, použijte metodu třídy fromkeys() typu dictionary nebo vestavěnou funkci sorted().

dict.fromkeys() vytvoří nový objekt slovníku, jehož klíče jsou seznamy, tuply atd. zadané v argumentech. Pokud je druhý argument vynechán, je hodnotou None.

Protože klíče slovníku nemají duplicitní prvky, jsou duplicitní hodnoty ignorovány stejně jako v set(). Kromě toho lze objekt slovníku předat jako argument funkci list() a získat tak seznam, jehož prvky jsou klíče slovníku.

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

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

Od verze Pythonu 3.7 (CPython je 3.6) je zaručeno, že funkce dict.fromkeys() zachovává pořadí posloupnosti argumentů. Dřívější verze používaly vestavěnou funkci sorted() následujícím způsobem.

Zadejte metodu index() pro argument sorted, která vrátí setříděný seznam prvků.

index() je metoda, která vrací index hodnoty (číslo prvku v seznamu), který lze zadat jako klíč metody sorted(), aby se seznam seřadil podle pořadí původního seznamu. Argument klíč se zadává jako volatelný (callable) objekt, proto nepište ().

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

Dvourozměrné pole (seznam seznamů)

U dvourozměrných polí (seznamů seznamů) vede metoda set() nebo dict.fromkeys() k 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'

Je tomu tak proto, že objekty, které se nedají hashovat, jako jsou seznamy, nemohou být prvky typu set nebo klíče typu dict.

Definujte následující funkce Pořadí původního seznamu je zachováno a funguje pro jednorozměrné seznamy a tuply.

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]

Používá se notace pro porozumění seznamu.

Zde používáme následující

  • Pokud je X v „X a Y“ při zkratkovém vyhodnocení operátoru and nepravdivé, pak se Y nevyhodnotí (neprovede).
  • Metoda append() vrací None.

Pokud prvky původního seznamu seq neexistují ve viděném, pak se vyhodnotí a after.
provede se seen.append(x) a prvek se přidá do souboru seen.
Protože metoda append() vrací None a None je False, not seen.append(x) se vyhodnotí jako True.
Podmíněný výraz v notaci pro porozumění seznamu se stane True a je přidán jako prvek konečného vygenerovaného seznamu.

Pokud jsou prvky původního seznamu seq přítomny v seznamu seen, pak x, který není v seznamu seen, je False a podmíněný výraz pro výraz porozumění seznamu je False.
Proto se nepřidávají jako prvky konečného vygenerovaného seznamu.

Další metodou je nastavení osy argumentů ve funkci NumPy np.unique(), i když výsledek bude setříděný.

Výběr duplicitních prvků a vytvoření nového seznamu

Nezachovávejte pořadí původního seznamu.

Chcete-li z původního seznamu získat pouze duplicitní prvky, použijte funkci collections.Counter().
Vrací soubor collections.Counter (podtřída slovníku) s prvky jako klíči a počtem prvků jako hodnotami.

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})

Protože se jedná o podtřídu slovníku, lze k získání klíčů a hodnot použít funkci items(). Stačí získat klíče, jejichž počet je dva nebo více.

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

Zachovává pořadí původního seznamu

Jak je ukázáno v příkladu výše, od verze Python 3.7 si klíče kolekce.Counter zachovávají pořadí původního seznamu atd.

V dřívějších verzích stačí třídění pomocí sorted(), stejně jako mazání duplicitních prvků.

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

Pokud chcete vyjmout duplikáty tak, jak jsou, jednoduše ponechte prvky z původního seznamu s číslem dva nebo více. Pořadí se rovněž zachová.

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

Dvourozměrné pole (seznam seznamů)

Pro dvourozměrná pole (seznamy seznamů) jsou možné následující funkce, pokud není zachováno pořadí původního seznamu a pokud je zachováno. Fungují také pro jednorozměrné seznamy a tuply.

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]

Pokud chcete extrahovat s duplicitami, ponechte prvky z původního seznamu s počtem dva nebo více.

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

Všimněte si, že vzhledem k tomu, že výpočetní složitost funkce count() je O(n), je výše uvedená funkce, která opakovaně provádí funkci count(), velmi neefektivní. Může existovat chytřejší způsob.

Čítač je podtřída slovníku, takže pokud funkci collections.Counter() předáte seznam nebo tuple, jehož prvky jsou seznamy nebo jiné objekty, které se nedají hashovat, dojde k chybě a nebude možné ji použít.

# print(collections.Counter(l_2d))
# TypeError: unhashable type: 'list'
Copied title and URL