Ovaj odjeljak opisuje kako generirati novi popis u Pythonu uklanjanjem ili izdvajanjem dupliciranih elemenata s popisa (niza).
Ovdje su opisani sljedeći detalji.
- Uklonite duple elemente i generirajte nove oglase
- Ne čuvajte redoslijed izvornog popisa:
set()
- Čuva redoslijed izvornog popisa:
dict.fromkeys()
,sorted()
- Dvodimenzionalni niz (popis popisa)
- Ne čuvajte redoslijed izvornog popisa:
- Izdvojite duple elemente i generirajte novi popis
- Ne čuvajte redoslijed izvornog popisa
- Čuva redoslijed izvornog popisa
- Dvodimenzionalni niz (popis popisa)
Isti koncept se može primijeniti na torke umjesto na liste.
Pogledajte sljedeći članak za
- Ako želite utvrditi ima li popis ili tuple duplicirane elemente
- Ako želite izdvojiti elemente koji su uobičajeni ili nisu uobičajeni među više unosa umjesto jednog unosa
Imajte na umu da popisi mogu pohranjivati različite vrste podataka i da se striktno razlikuju od nizova. Ako želite rukovati nizovima u procesima koji zahtijevaju veličinu memorije i memorijske adrese ili numeričku obradu velikih podataka, koristite niz (standardna biblioteka) ili NumPy.
Uklonite duple elemente i generirajte nove oglase
Ne čuvajte redoslijed izvornog popisa:set()
Ako nema potrebe za očuvanjem redoslijeda izvornog popisa, koristite set(), koji generira skup tipa skupa.
Vrsta skupa je vrsta podataka koja nema duple elemente. Kada se popis ili drugi tip podataka prosljeđuje set(), duplicirane vrijednosti se zanemaruju i vraća se objekt tipa set u kojem su samo jedinstvene vrijednosti elementi.
Ako ga želite napraviti kao tuple, koristite 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]
Naravno, može se ostaviti i postavljeno. Pogledajte sljedeći članak za više informacija o skupu vrste skupa.
Čuva redoslijed izvornog popisa:dict.fromkeys(),sorted()
Ako želite sačuvati redoslijed izvornog popisa, koristite metodu klase fromkeys() tipa rječnika ili ugrađenu funkciju sorted().
dict.fromkeys() stvara novi objekt rječnika čiji su ključevi liste, torke itd. navedeni u argumentima. Ako je drugi argument izostavljen, vrijednost je Ništa.
Budući da ključevi rječnika nemaju duple elemente, duplicirane vrijednosti se zanemaruju kao u set(). Osim toga, objekt rječnika može se proslijediti kao argument listi() za dobivanje popisa čiji su elementi ključevi rječnika.
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 Pythona 3.7 (CPython je 3.6) zajamčeno je da dict.fromkeys() čuva redoslijed niza argumenata. Ranije verzije koriste ugrađenu funkciju sorted() kako slijedi.
Odredite index() metode torke popisa za ključ argumenta sorted, koji vraća sortirani popis elemenata.
index() je metoda koja vraća indeks vrijednosti (broj elementa na popisu), koji se može navesti kao ključ sorted() za sortiranje popisa na temelju redoslijeda izvornog popisa. Ključ argumenata je naveden kao objekt koji se može pozvati (poziv), stoga nemojte pisati ().
print(sorted(set(l), key=l.index))
# [3, 2, 1, 5, 4]
Dvodimenzionalni niz (popis popisa)
Za dvodimenzionalne nizove (liste popisa), metoda koja koristi set() ili dict.fromkeys() rezultira 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'
To je zato što objekti koji se ne mogu raspršiti kao što su popisi ne mogu biti elementi skupa tipa ili ključevi tipa dict.
Definirajte sljedeće funkcije. Redoslijed izvornog popisa je očuvan i radi za jednodimenzionalne popise i torke.
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]
Koristi se zapis razumijevanja popisa.
Ovdje koristimo sljedeće
- Ako je X u “X i Y” netočan u procjeni kratkog spoja operatora i, tada se Y ne evaluira (ne izvršava se).
- Metoda append() vraća Ništa.
Ako elementi originalnog popisa seq ne postoje u viđenom, onda i poslije se evaluiraju.
seen.append(x) se izvršava i element se dodaje u seen.
Budući da metoda append() vraća None, a None je False, not seen.append(x) daje vrijednost True.
Uvjetni izraz u zapisu za razumijevanje popisa postaje True i dodaje se kao element konačno generiranog popisa.
Ako su elementi izvornog popisa seq prisutni u seen, tada je x not in seen False, a uvjetni izraz za izraz za razumijevanje popisa je False.
Stoga se ne dodaju kao elementi konačno generiranog popisa.
Druga metoda je postavljanje osi argumenata u funkciji NumPy np.unique(), iako će rezultat biti sortiran.
Izdvojite duple elemente i generirajte novi popis
Ne čuvajte redoslijed izvornog popisa
Za izdvajanje samo dupliciranih elemenata s izvornog popisa, koristite collections.Counter().
Vraća zbirku. Brojač (podklasa rječnika) s elementima kao ključevima i brojem elemenata kao vrijednostima.
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})
Budući da je riječ o podklasi rječnika, items() se može koristiti za dohvaćanje ključeva i vrijednosti. Dovoljno je izdvojiti ključeve čiji je broj dva ili više.
print([k for k, v in collections.Counter(l).items() if v > 1])
# [3, 2, 1]
Čuva redoslijed izvornog popisa
Kao što je prikazano u gornjem primjeru, od Pythona 3.7, ključevi zbirki.Counter zadržavaju redoslijed izvornog popisa i tako dalje.
U ranijim verzijama, sortiranje pomoću sorted() je dovoljno, kao i brisanje dupliciranih elemenata.
print(sorted([k for k, v in collections.Counter(l).items() if v > 1], key=l.index))
# [3, 2, 1]
Ako želite izdvojiti duplikate kakve jesu, jednostavno ostavite elemente s izvornog popisa s brojem od dva ili više. Očuvan je i red.
cc = collections.Counter(l)
print([x for x in l if cc[x] > 1])
# [3, 3, 2, 1, 1, 2, 3]
Dvodimenzionalni niz (popis popisa)
Za dvodimenzionalne nizove (liste popisa) sljedeće funkcije su moguće kada se redoslijed izvornog popisa ne zadržava, odnosno kada se zadržava. Također radi za jednodimenzionalne liste i torke.
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]
Ako želite izdvojiti s duplikatima, ostavite elemente s izvornog popisa s brojem dva ili više.
print([x for x in l_2d if l_2d.count(x) > 1])
# [[1, 1], [0, 1], [0, 1], [1, 1], [1, 1]]
Imajte na umu da je složenost računanja count() O(n), gore prikazana funkcija koja više puta izvršava count() vrlo je neučinkovita. Možda postoji pametniji način.
Brojač je podklasa rječnika, tako da ako proslijedite listu ili torku čiji su elementi liste ili drugi objekti koji se ne mogu raspršiti u collections.Counter(), pojavit će se pogreška i nećete je moći koristiti.
# print(collections.Counter(l_2d))
# TypeError: unhashable type: 'list'