Melko paljon minun täytyy kirjoittaa ohjelma, jolla tarkistetaan, onko luettelossa päällekkäisyyksiä, ja jos on, se poistaa ne ja palauttaa uuden luettelon, jossa on kohteita, jotka eivät ole päällekkäisiä / poistettuja. Minulla on tämä, mutta rehellisesti sanottuna en tiedä, mitä tehdä.
def remove_duplicates():
t = ['a', 'b', 'c', 'd']
t2 = ['a', 'c', 'd']
for t in t2:
t.append(t.remove())
return t
Yleinen tapa saada yksilöllinen kokoelma kohteita on käyttää set
. Joukot ovat järjestämättömiä kokoelmia erillisiä objekteja. Voit luoda joukon mistä tahansa iterablesta yksinkertaisesti antamalla sen sisäänrakennetulle set()
-funktiolle. Jos myöhemmin tarvitset taas todellisen listan, voit samalla tavalla antaa joukon list()
-funktiolle.
Seuraavan esimerkin pitäisi kattaa kaikki, mitä yritätkin tehdä:
>>> 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]
Kuten esimerkin tuloksesta näkyy, alkuperäistä järjestystä ei säilytetä. Kuten edellä mainittiin, joukot itsessään ovat järjestämättömiä kokoelmia, joten järjestys katoaa. Kun joukko muunnetaan takaisin listaksi, luodaan mielivaltainen järjestys.
Jos järjestys on sinulle tärkeää, sinun on käytettävä eri mekanismia. Hyvin yleinen ratkaisu tähän on luottaa OrderedDict
:iin avainten järjestyksen säilyttämiseksi lisäämisen aikana:
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
Python 3.7:stä alkaen sisäänrakennettu sanakirja säilyttää taatusti myös lisäysjärjestyksen, joten voit käyttää sitä myös suoraan, jos käytät Python 3.7:ää tai uudempaa (tai CPython 3.6:ta):
>>> list(dict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
Huomaa, että tämä aiheuttaa sen, että ensin luodaan sanakirja ja sitten siitä lista. Jos järjestystä ei oikeastaan tarvitse säilyttää, on parempi käyttää joukkoa. Katso tämä kysymys, josta saat lisätietoja ja vaihtoehtoisia tapoja säilyttää järjestys poistettaessa kaksoiskappaleita.
Huomaa lopuksi, että sekä set
- että OrderedDict
/dict
-ratkaisut edellyttävät, että kohteet ovat hashattavissa. Tämä tarkoittaa yleensä sitä, että niiden on oltava muuttumattomia. Jos joudut käsittelemään kohteita, jotka eivät ole hajautettavissa (esim. listaobjektit), sinun on käytettävä hidasta lähestymistapaa, jossa sinun on periaatteessa verrattava jokaista kohdetta jokaiseen toiseen kohteeseen sisäkkäisessä silmukassa.
Se on yksirivinen: list(set(source_list))
tekee tempun.
set
on jotain, jossa ei voi olla kaksoiskappaleita.
Päivitys: järjestyksen säilyttävä lähestymistapa on kaksi riviä:
from collections import OrderedDict
OrderedDict((x, True) for x in source_list).keys()
Tässä käytetään hyväksi sitä, että OrderedDict
muistaa avainten lisäämisen järjestyksen eikä muuta sitä, kun tietyn avaimen arvo päivitetään. Lisäämme True
-arvoja, mutta voisimme lisätä mitä tahansa, arvoja ei vain käytetä. (set
toimii paljolti kuin dict
, jossa on myös huomiotta jätettyjä arvoja.)