Duplikált elemek eltávolítása és kivonása egy listából (tömb) Pythonban

Üzleti

Ez a szakasz leírja, hogyan hozhatunk létre egy új listát Pythonban úgy, hogy eltávolítjuk vagy kivonjuk a duplikált elemeket egy listából (tömbből).

A következő részleteket ismertetjük.

  • Duplikált elemek eltávolítása és új listák létrehozása
    • Ne őrizze meg az eredeti felsorolás sorrendjét:set()
    • Megőrzi az eredeti lista sorrendjét: dict.fromkeys(),sorted()
    • Kétdimenziós tömb (listák listája)
  • Duplikált elemek kivonása és új lista létrehozása
    • Ne őrizze meg az eredeti felsorolás sorrendjét
    • Megőrzi az eredeti lista sorrendjét
    • Kétdimenziós tömb (listák listája)

Ugyanez a koncepció alkalmazható a listák helyett a tuplikra is.

Lásd a következő cikket

  • Ha meg akarja határozni, hogy egy lista vagy egy tuple tartalmaz-e duplikált elemeket
  • Ha egyetlen listázás helyett több listázásban közös vagy nem közös elemeket szeretne kivonatolni

Vegye figyelembe, hogy a listák különböző típusú adatokat tárolhatnak, és szigorúan különböznek a tömböktől. Ha olyan folyamatokban szeretnénk tömböket kezelni, amelyek memóriaméretet és memóriacímeket vagy nagyméretű adatok numerikus feldolgozását igénylik, használjuk a array (standard könyvtár) vagy a NumPy programot.

Duplikált elemek eltávolítása és új listák létrehozása

Ne őrizze meg az eredeti felsorolás sorrendjét: set()

Ha nincs szükség az eredeti lista sorrendjének megőrzésére, használjuk a set() funkciót, amely egy set típusú set-et generál.

A halmaz típus olyan adattípus, amelynek nincsenek duplikált elemei. Ha egy listát vagy más adattípust adunk át a set() függvénynek, a duplikált értékeket figyelmen kívül hagyjuk, és egy olyan set típusú objektumot kapunk vissza, amelyben csak egyedi értékek az elemek.

Ha tuple-t akarsz belőle csinálni, használd a tuple() funkciót.

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]

Természetesen meghagyható úgy is, ahogy van beállítva. A set típusról bővebben a következő cikkben olvashat a set típusról.

Megőrzi az eredeti lista sorrendjét: dict.fromkeys(),sorted()

Ha meg akarja őrizni az eredeti lista sorrendjét, használja a szótár típus fromkeys() osztálymódszerét vagy a beépített sorted() függvényt.

A dict.fromkeys() egy új szótár objektumot hoz létre, amelynek kulcsai az argumentumokban megadott listák, tuplik stb. Ha a második argumentum kimarad, az érték None.

Mivel a szótárkulcsok nem tartalmaznak duplikált elemeket, a duplikált értékek figyelmen kívül maradnak, mint a set() esetében. Ezen kívül egy szótár objektumot átadhatunk argumentumként a list()-nak, hogy egy olyan listát kapjunk, amelynek elemei szótári kulcsok.

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

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

A Python 3.7 óta (a CPython 3.6-os) garantált, hogy a dict.fromkeys() megőrzi az argumentumok sorrendjét. A korábbi verziók a beépített sorted() függvényt használják a következőképpen.

Adja meg a listatömbök index() metódusát a sorted argumentum kulcsához, amely az elemek rendezett listáját adja vissza.

Az index() egy olyan metódus, amely visszaadja az érték indexét (a lista elemének számát), amelyet a sorted() kulcsaként adhatunk meg, hogy a listát az eredeti lista sorrendje alapján rendezzük. A kulcs argumentumot hívható (callable) objektumként adjuk meg, tehát ne írjuk ki ().

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

Kétdimenziós tömb (listák listája)

Kétdimenziós tömbök (listák listái) esetén a set() vagy a dict.fromkeys() módszer TypeError-t eredményez.

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'

Ennek az az oka, hogy az olyan nem-kapcsolt objektumok, mint a listák, nem lehetnek set típusú elemek vagy dict típusú kulcsok.

Definiálja a következő függvényeket Az eredeti lista sorrendje megmarad, és egydimenziós listák és tuplik esetén működik.

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]

Listaszerű jelölést használunk.

Itt a következőket használjuk

  • Ha az “X és Y” kifejezésben az X hamis az and operátor rövidzárlatos kiértékelésében, akkor az Y nem kerül kiértékelésre (nem hajtódik végre).
  • Az append() metódus nem ad vissza semmit.

Ha az eredeti seq lista elemei nem léteznek a látottakban, akkor a és utána értékelődik ki.
A seen.append(x) végrehajtásra kerül, és az elem hozzáadódik a seen-hez.
Mivel az append() metódus None-t ad vissza, a None pedig False, a not seen.append(x) értéke True.
A feltételes kifejezés a listamegértés jelölésében Igaz lesz, és a végső generált lista egyik elemeként hozzáadódik.

Ha az eredeti lista seq elemei jelen vannak a seen-ben, akkor a seen-ben nem szereplő x hamis, és a lista megértésének feltételes kifejezése hamis.
Ezért ezek nem kerülnek hozzáadásra a végső generált lista elemeiként.

Egy másik módszer az argumentum tengelyének beállítása a NumPy np.unique() függvényében, bár az eredmény rendezett lesz.

Duplikált elemek kivonása és új lista létrehozása

Ne őrizze meg az eredeti felsorolás sorrendjét

Ha csak a duplikált elemeket szeretné kivenni az eredeti listából, használja a collections.Counter() funkciót.
Visszaad egy collections.Counter-t (a dictionary egy alosztálya) az elemekkel mint kulcsokkal és az elemek számával mint értékekkel.

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

Mivel ez a dictionary alosztálya, az items() funkció használható a kulcsok és értékek lekérdezésére. Elegendő olyan kulcsok kinyerése, amelyek száma kettő vagy több.

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

Megőrzi az eredeti lista sorrendjét

Ahogy a fenti példában látható, a Python 3.7 óta a collections.Counter kulcsai megtartják az eredeti lista sorrendjét, és így tovább.

A korábbi verziókban elegendő a sorted() funkcióval történő rendezés, valamint a duplikált elemek törlése.

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

Ha a duplikátumokat úgy szeretné kivenni, ahogy vannak, egyszerűen hagyja meg az eredeti lista azon elemeit, amelyek száma kettő vagy annál több. A sorrend is megmarad.

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

Kétdimenziós tömb (listák listája)

Kétdimenziós tömbök (listák listái) esetén a következő függvények lehetségesek, ha az eredeti lista sorrendje nem marad meg, illetve ha megmarad. Ez egydimenziós listák és tuplik esetében is működik.

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]

Ha duplikátumokkal akarja kivenni, hagyja meg az eredeti listából azokat az elemeket, amelyek száma kettő vagy több.

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

Vegyük észre, hogy mivel a count() számítási bonyolultsága O(n), a fenti függvény, amely ismételten végrehajtja a count()-t, nagyon nem hatékony. Lehet, hogy van egy okosabb megoldás.

A Counter a dictionary alosztálya, így ha olyan listát vagy tuple-t adsz át a collections.Counter() függvénynek, amelynek elemei listák vagy más, nem zárolható objektumok, hiba fog jelentkezni, és nem fogod tudni használni.

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