Ondoa na utoe nakala mbili kutoka kwa orodha (safu) kwenye Python

Biashara

Sehemu hii inaelezea jinsi ya kutengeneza orodha mpya katika Python kwa kuondoa au kutoa nakala kutoka kwa orodha (safu).

Maelezo yafuatayo yanaelezwa hapa.

  • Ondoa vipengele vilivyorudiwa na utengeneze uorodheshaji mpya
    • Usihifadhi mpangilio wa uorodheshaji asili:set()
    • Huhifadhi mpangilio wa uorodheshaji asili:dict.fromkeys(),sorted()
    • Safu ya pande mbili (orodha ya orodha)
  • Chambua vipengee vilivyorudiwa na utengeneze orodha mpya
    • Usihifadhi mpangilio wa uorodheshaji asili
    • Huhifadhi mpangilio wa uorodheshaji asili
    • Safu ya pande mbili (orodha ya orodha)

Dhana hiyo hiyo inaweza kutumika kwa nakala badala ya orodha.

Tazama makala ifuatayo kwa

  • Ikiwa ungependa kubainisha ikiwa orodha au nakala ina vipengee vinavyorudiwa
  • Iwapo ungependa kutoa vipengele ambavyo ni vya kawaida au visivyo vya kawaida miongoni mwa uorodheshaji nyingi badala ya uorodheshaji mmoja

Kumbuka kuwa orodha zinaweza kuhifadhi aina tofauti za data na ni tofauti kabisa na safu. Ikiwa ungependa kushughulikia safu katika michakato inayohitaji ukubwa wa kumbukumbu na anwani za kumbukumbu au usindikaji wa nambari za data kubwa, tumia safu (maktaba ya kawaida) au NumPy.

Ondoa vipengele vilivyorudiwa na utengeneze uorodheshaji mpya

Usihifadhi mpangilio wa uorodheshaji asili:set()

Ikiwa hakuna haja ya kuhifadhi mpangilio wa orodha ya asili, tumia set(), ambayo hutoa seti ya aina iliyowekwa.

Aina ya seti ni aina ya data ambayo haina vipengele vya nakala. Orodha au aina nyingine ya data inapopitishwa kwa set(), thamani rudufu hupuuzwa na kitu cha aina hurejeshwa ambacho ni vipengee vya kipekee pekee.

Ikiwa unataka kuifanya tuple, tumia 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]

Bila shaka, inaweza pia kushoto kama kuweka. Tazama nakala ifuatayo kwa habari zaidi juu ya seti ya aina iliyowekwa.

Huhifadhi mpangilio wa uorodheshaji asili:dict.fromkeys(),sorted()

Ikiwa ungependa kuhifadhi mpangilio wa orodha asili, tumia mbinu ya darasa fromkeys() ya aina ya kamusi au chaguo za kukokotoa zilizojumuishwa zilizopangwa().

dict.fromkeys() huunda kipengee kipya cha kamusi ambacho funguo zake ni orodha, nakala, n.k. zilizobainishwa katika hoja. Hoja ya pili ikiachwa, thamani ni Hakuna.

Kwa kuwa vitufe vya kamusi havina vipengee vinavyorudiwa, thamani rudufu hupuuzwa kama ilivyo katika set(). Kwa kuongezea, kipengee cha kamusi kinaweza kupitishwa kama hoja ya list() ili kupata orodha ambayo vipengele vyake ni vitufe vya kamusi.

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

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

Imehakikishwa tangu Python 3.7 (CPython ni 3.6) kwamba dict.fromkeys() huhifadhi mpangilio wa mlolongo wa hoja. Matoleo ya awali hutumia chaguo la kukokotoa lililojengwa ndani sorted() kama ifuatavyo.

Bainisha orodha ya njia ya tuple index() kwa ufunguo wa hoja wa kupangwa, ambao hurejesha orodha ya vipengele vilivyopangwa.

index() ni njia inayorudisha faharasa ya thamani (idadi ya kipengele kwenye orodha), ambayo inaweza kubainishwa kama ufunguo wa sorted() kupanga orodha kulingana na mpangilio wa orodha asili. Ufunguo wa hoja umebainishwa kama kitu kinachoweza kupigiwa simu (kinachoweza kupigiwa simu), kwa hivyo usiandike ().

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

Safu ya pande mbili (orodha ya orodha)

Kwa safu za pande mbili (orodha za orodha), mbinu ya kutumia set() au dict.fromkeys() husababisha 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'

Hii ni kwa sababu vitu visivyoweza kuharibika kama vile orodha haviwezi kuwa vipengele vya seti ya aina au funguo za aina ya dict.

Bainisha vitendaji vifuatavyo Mpangilio wa orodha asili huhifadhiwa na hufanya kazi kwa orodha zenye mwelekeo mmoja na nakala.

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]

Uelewa wa orodha hutumiwa.

Hapa, tunatumia zifuatazo

  • Ikiwa X katika “X na Y” ni ya uwongo katika tathmini ya mzunguko mfupi wa opereta, basi Y haijatathminiwa (haijatekelezwa).
  • Njia ya append() inarudi Hakuna.

Ikiwa vipengele vya orodha ya asili ya seq havipo kwenye inayoonekana, basi na baada ya kutathminiwa.
seen.append(x) inatekelezwa na kipengele kinaongezwa ili kuonekana.
Kwa sababu njia ya append() inarejesha Hakuna na Hakuna Isiyo kweli, haijaonekana.append(x) inatathmini kuwa Kweli.
Usemi wa masharti katika nukuu ya ufahamu wa orodha unakuwa Kweli na huongezwa kama kipengele cha orodha ya mwisho iliyotolewa.

Ikiwa vipengee vya seki ya orodha asili vipo inavyoonekana, basi x isiyoonekana ni Siyo, na usemi wa masharti wa usemi wa ufahamu wa orodha ni Uongo.
Kwa hivyo, hazijaongezwa kama vipengele vya orodha ya mwisho inayozalishwa.

Njia nyingine ni kuweka mhimili wa hoja katika kazi ya NumPy np.unique(), ingawa matokeo yatapangwa.

Chambua vipengee vilivyorudiwa na utengeneze orodha mpya

Usihifadhi mpangilio wa uorodheshaji asili

Ili kutoa vipengele vinavyorudiwa pekee kutoka kwenye orodha asili, tumia collections.Counter().
Hurejesha mikusanyiko. Kaunta (daraja ndogo ya kamusi) yenye vipengele kama funguo na idadi ya vipengele kama thamani.

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

Kwa kuwa ni aina ndogo ya kamusi, vitu() vinaweza kutumika kupata vitufe na maadili. Inatosha kutoa funguo ambazo nambari yake ni mbili au zaidi.

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

Huhifadhi mpangilio wa uorodheshaji asili

Kama inavyoonyeshwa kwenye mfano hapo juu, tangu Python 3.7, funguo za makusanyo.Counter huhifadhi mpangilio wa orodha asili na kadhalika.

Katika matoleo ya awali, kupanga na sorted() inatosha, kama vile kufuta vipengele vinavyorudiwa.

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

Ikiwa ungependa kutoa nakala jinsi zilivyo, acha tu vipengele kutoka kwenye orodha asili na idadi ya mbili au zaidi. Agizo pia limehifadhiwa.

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

Safu ya pande mbili (orodha ya orodha)

Kwa safu za pande mbili (orodha za orodha), chaguo za kukokotoa zifuatazo zinawezekana wakati mpangilio wa orodha asilia haujahifadhiwa na unapohifadhiwa, mtawalia. Pia inafanya kazi kwa orodha za sura moja na nakala.

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]

Ikiwa ungependa kutoa na nakala, acha vipengee kutoka kwa orodha asili na hesabu ya mbili au zaidi.

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

Kumbuka kuwa kwa kuwa uchangamano wa hesabu wa count() ni O(n), chaguo la kukokotoa lililoonyeshwa hapo juu ambalo hutekeleza mara kwa mara count() halifai sana. Kunaweza kuwa na njia nadhifu zaidi.

Counter ni aina ndogo ya kamusi, kwa hivyo ukipitisha orodha au nakala ambazo vipengele vyake ni orodha au vitu vingine visivyoweza kuharibika kwa collections.Counter(), hitilafu itatokea na hutaweza kuitumia.

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