Di Python de hêmanên dubare ji navnîşek (array) derxînin û derxin

Dikan

Ev beş rave dike ku meriv çawa di Python de navnîşek nû bi hilanîn an derxistina hêmanên dubare ji navnîşek (array) çêdike.

Agahiyên jêrîn li vir têne diyar kirin.

  • Hêmanên dubare rakin û navnîşên nû biafirînin
    • Rêza navnîşa orîjînal neparêzin:set()
    • Rêza navnîşa orîjînal diparêze:dict.fromkeys(),sorted()
    • Rêzeya du-alî (lîsteya navnîşan)
  • Hêmanên dubare derxînin û navnîşek nû çêbikin
    • Rêza navnîşa orîjînal neparêzin
    • Rêza navnîşa orîjînal diparêze
    • Rêzeya du-alî (lîsteya navnîşan)

Heman têgeh dikare li şûna navnîşan li ser tîpan were sepandin.

Ji bo gotara jêrîn bibînin

  • Ger hûn dixwazin diyar bikin ka navnîşek an pirtikek hêmanên dubare hene
  • Heke hûn dixwazin li şûna navnîşek yekane hêmanên ku di nav pir navnîşan de hevpar in an ne hevpar in derxînin

Bala xwe bidinê ku navnîş dikarin cûreyên cûda yên daneyan hilînin û bi tundî ji rêzan cûda ne. Heke hûn dixwazin di pêvajoyên ku hewceyê mezinahiya bîranînê û navnîşanên bîranînê an pêvajoya hejmarî ya daneyên mezin hewce dikin de rêzan bi rê ve bibin, array (pirtûkxaneya standard) an NumPy bikar bînin.

Hêmanên dubare rakin û navnîşên nû biafirînin

Rêza navnîşa orîjînal neparêzin:set()

Ger ne hewce ye ku rêza navnîşa orîjînal were parastin, set() bikar bînin, ku komek celebek sazûman çêdike.

Tîpa set cureyek daneyê ye ku hêmanên wê yên dubare tune. Dema ku navnîşek an celebek din a daneyê ji set() re derbas dibe, nirxên dubare têne paşguh kirin û tiştek celeb celeb tê vegerandin ku tê de tenê nirxên bêhempa hêman in.

Heke hûn dixwazin wê bikin tuple, tuple() bikar bînin.

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]

Bê guman, ew dikare wekî sazkirî jî were hiştin. Ji bo bêtir agahdarî li ser celebê setê li gotara jêrîn binêrin.

Rêza navnîşa orîjînal diparêze:dict.fromkeys(),sorted()

Heke hûn dixwazin rêza navnîşa orîjînal biparêzin, rêbaza polê fromkeys() ya celebê ferhengê an fonksiyona çêkirî ya sorted() bikar bînin.

dict.fromkeys() hêmaneke ferhengê ya nû diafirîne ku bişkojkên wê lîste, pirtik û hwd in ku di argumanan de hatine diyarkirin. Ger argumana duyemîn ji holê rabe, nirx Tune ye.

Ji ber ku bişkokên ferhengê hêmanên dubare nînin, nirxên dubare wekî di set() de têne paşguh kirin. Digel vê yekê, tişta ferhengê dikare wekî argumanek ji navnîşê () re were derbas kirin da ku navnîşek ku hêmanên wê kilîtên ferhengê ne bi dest bixe.

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

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

Ji Python 3.7 (CPython 3.6 e) ve hatî garantî kirin ku dict.fromkeys() rêza rêzika argumanan diparêze. Guhertoyên berê fonksiyona çêkirî ya sorted() wekî jêrîn bikar tînin.

Ji bo mifteya argumanê ya birêkûpêk, ku navnîşek birêkûpêk a hêmanan vedigerîne, navnîşa rêbaza piralî index() diyar bikin.

index() rêbazek e ku îndeksa nirxê vedigerîne (hejmara hêmana di navnîşê de), ku dikare wekî mifteya sorted() were destnîşan kirin da ku navnîşê li gorî rêza navnîşa orîjînal rêz bike. Mifteya argûmanan wekî tişta ku tê bangkirin (binavkirin) tê destnîşan kirin, ji ber vê yekê () nenivîse.

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

Rêzeya du-alî (lîsteya navnîşan)

Ji bo rêzikên du-alî (lîsteyên lîsteyan), rêbaza ku set() an dict.fromkeys() bikar tîne di TypeError de encam dide.

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'

Ji ber ku tiştên ne-hashbar ên wekî navnîşan nikarin hêmanên cûrbecûr set an bişkojkên celebê dict bin.

Fonksiyonên jêrîn diyar bikin Rêza lîsteya orîjînal tê parastin û ji bo lîsteyên yek-alî û tîpan dixebite.

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]

Nîşana têgihîştina navnîşê tê bikar anîn.

Li vir, em jêrîn bikar tînin

  • Ger X-ya di “X û Y” de di nirxandina gerîdeya kurt a û operatorê de xelet be, wê hingê Y nayê nirxandin (ne darvekirin).
  • Rêbaza append() Tune vedigerîne.

Ger hêmanên lîsteya orîjînal seq di dîtinê de tune bin, wê hingê û paşê têne nirxandin.
dîtin.append(x) tê îdamkirin û hêman li dîtinê tê zêdekirin.
Ji ber ku rêbaza append() None vedigere û None is False, nayê dîtin.append(x) dinirxîne True.
Gotina şertî di navnîşa têgihîştina navnîşê de rast dibe û wekî hêmanek navnîşa hilberandina dawîn tê zêdekirin.

Ger hêmanên navnîşa orîjînal seq di dîtinê de hebin, wê hingê x ku nayê dîtin xelet e, û îfadeya şertî ya ji bo îfadeya têgihîştina navnîşê xelet e.
Ji ber vê yekê, ew wekî hêmanên navnîşa paşîn a hilberandî nayê zêdekirin.

Rêbazek din ev e ku hûn eksê argumanê di fonksiyona NumPy-yê np.unique() de bicîh bikin, her çend encam dê were rêz kirin.

Hêmanên dubare derxînin û navnîşek nû çêbikin

Rêza navnîşa orîjînal neparêzin

Ji bo ku tenê hêmanên dubare ji navnîşa orîjînal derxînin, collections.Counter() bikar bînin.
Koleksiyonek vedigerîne.Hejmar (binavçenga ferhengê) bi hêmanan wek kilît û hejmara hêmanan wekî nirx.

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

Ji ber ku ew binklassek ferhengê ye, hêman() dikare were bikar anîn da ku mift û nirxan werbigire. Derxistina kilîtên ku hejmara wan du an jî zêdetir e bes e.

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

Rêza navnîşa orîjînal diparêze

Mîna ku di mînaka li jor de tê xuyang kirin, ji Python 3.7 ve, mifteyên berhevokan. Counter rêza lîsteya orîjînal diparêze û hwd.

Di guhertoyên berê de, birêkûpêkkirina bi sorted() bes e, her weha jêbirina hêmanên dubare bes e.

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

Heke hûn dixwazin wekî wan dubareyan derxînin, tenê hêmanên ji navnîşa orîjînal bi hejmarek du an jî zêdetir bihêlin. Ferman jî tê parastin.

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

Rêzeya du-alî (lîsteya navnîşan)

Ji bo rêzikên du-alî (lîsteyên navnîşan), fonksiyonên jêrîn bi rêzdarî dema ku rêza navnîşa orîjînal neyê girtin û dema ku ew were girtin, gengaz in. Di heman demê de ew ji bo lîsteyên yek-alî û tîpan jî dixebite.

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]

Heke hûn dixwazin bi dubareyan derxînin, hêmanên ji navnîşa orîjînal bi jimareyek du an zêdetir bihêlin.

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

Bala xwe bidinê ku ji ber ku tevliheviya jimartinê () O(n) ye, fonksiyona ku li jor hatî xuyang kirin ku çend caran jimartinê() dimeşîne pir bêkêr e. Dibe ku rêyek jîrtir hebe.

Counter binkifla ferhengê ye, ji ber vê yekê ger hûn lîsteyek an pirteyek ku hêmanên wê lîste an tiştên din ên ku nayên haşkirin derbas bikin, bidin berhevokan.Counter(), dê xeletiyek çêbibe û hûn ê nikaribin wê bikar bînin.

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