Përdorimi i shënimit të kuptimit të listës Python

biznes

Në Python, është e thjeshtë të përdoret shënimi i kuptimit të listës kur krijon një listë të re.(List comprehensions)

Në këtë artikull, së pari do të diskutojmë sa vijon

  • Lloji bazë i shënimit të kuptimit të listës
  • Listoni shënimet e të kuptuarit me degëzim të kushtëzuar nga if
  • Kombinim me operatorë tresh (nëse përpunohet si një tjetër)
  • zip(),enumerate()Kombinimi me këto
  • shënimi i përfshirjes së listës së mbivendosur

Më pas, ne do të shpjegojmë grupin e shënimeve të kuptimit të listës me kodin e mostrës.

  • vendos shënimin e përfshirjes(Set comprehensions)
  • shënimi i përfshirjes së fjalorit(Dict comprehensions)
  • lloji i gjeneratorit(Generator expressions)

Lloji bazë i shënimit të kuptimit të listës

Shënimi i të kuptuarit të listës shkruhet si më poshtë.

[Expression for Any Variable Name in Iterable Object]

Ai merr çdo element të një objekti të përsëritur si një listë, tuple ose varg me një emër të variablit arbitrar dhe e vlerëson atë me një shprehje. Kthehet një listë e re me rezultatin e vlerësimit si element.

Një shembull është dhënë së bashku me një ekuivalent për deklaratë.

squares = [i**2 for i in range(5)]
print(squares)
# [0, 1, 4, 9, 16]
squares = []
for i in range(5):
    squares.append(i**2)

print(squares)
# [0, 1, 4, 9, 16]

I njëjti proces mund të bëhet me map(), por shënimi i të kuptuarit të listës preferohet për thjeshtësinë dhe qartësinë e tij.

Listoni shënimet e të kuptuarit me degëzim të kushtëzuar nga if

Degëzimi i kushtëzuar me nëse është gjithashtu i mundur. Shkruani if-në në postfiks si më poshtë.

[Expression for Any Variable Name in Iterable Object if Conditional Expression]

Vetëm elementët e objektit të përsëritur, shprehja e kushtëzuar e të cilit është e vërtetë vlerësohen nga shprehja dhe kthehet një listë e re, elementët e së cilës janë rezultati.

Ju mund të përdorni çdo emër të ndryshores në shprehjen e kushtëzuar.

Një shembull është dhënë së bashku me një ekuivalent për deklaratë.

odds = [i for i in range(10) if i % 2 == 1]
print(odds)
# [1, 3, 5, 7, 9]
odds = []
for i in range(10):
    if i % 2 == 1:
        odds.append(i)

print(odds)
# [1, 3, 5, 7, 9]

I njëjti proces mund të bëhet me filter(), por shënimi i të kuptuarit të listës preferohet për thjeshtësinë dhe qartësinë e tij.

Kombinim me operatorë tresh (nëse përpunohet si një tjetër)

Në shembullin e mësipërm, përpunohen vetëm ato elemente që plotësojnë kriteret dhe ato që nuk plotësojnë kriteret përjashtohen nga lista e re.

Nëse dëshironi të ndërroni procesin në varësi të kushtit, ose nëse dëshironi të përpunoni elementë që nuk e plotësojnë kushtin ndryshe, si në qoftë se tjetër, përdorni operatorin tresh.

Në Python, operatori tresh mund të shkruhet si më poshtë

Value When True if Conditional Expression else Value When False

Kjo përdoret në pjesën e shprehjes së shënimit të kuptimit të listës siç tregohet më poshtë.

[Value When True if Conditional Expression else Value When False for Any Variable Name in Iterable Object]

Një shembull është dhënë së bashku me një ekuivalent për deklaratë.

odd_even = ['odd' if i % 2 == 1 else 'even' for i in range(10)]
print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']
odd_even = []
for i in range(10):
    if i % 2 == 1:
        odd_even.append('odd')
    else:
        odd_even.append('even')

print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']

Është gjithashtu e mundur të shkruhen shprehje duke përdorur emra arbitrar të ndryshoreve për vlerat e vërteta dhe të rreme.

Nëse kushti është i plotësuar, bëhet një përpunim, përndryshe vlera e objektit origjinal iterable mbetet e pandryshuar.

odd10 = [i * 10 if i % 2 == 1 else i for i in range(10)]
print(odd10)
# [0, 10, 2, 30, 4, 50, 6, 70, 8, 90]

Kombinim me zip() dhe enumerate()

Funksionet e dobishme që përdoren shpesh në deklaratën for përfshijnë zip(), i cili kombinon përsëritje të shumta dhe enumerate(), i cili kthen një vlerë së bashku me indeksin e saj.

Sigurisht, është e mundur të përdoren zip() dhe enumerate() me shënimin e kuptimit të listës. Nuk është një sintaksë e veçantë dhe nuk është e vështirë nëse merrni parasysh korrespondencën me deklaratën për.

Shembull i zip().

l_str1 = ['a', 'b', 'c']
l_str2 = ['x', 'y', 'z']

l_zip = [(s1, s2) for s1, s2 in zip(l_str1, l_str2)]
print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]
l_zip = []
for s1, s2 in zip(l_str1, l_str2):
    l_zip.append((s1, s2))

print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]

Shembull i enumerate().

l_enu = [(i, s) for i, s in enumerate(l_str1)]
print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]
l_enu = []
for i, s in enumerate(l_str1):
    l_enu.append((i, s))

print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]

Ideja është e njëjtë si më parë kur përdorni if.

l_zip_if = [(s1, s2) for s1, s2 in zip(l_str1, l_str2) if s1 != 'b']
print(l_zip_if)
# [('a', 'x'), ('c', 'z')]

Çdo element mund të përdoret gjithashtu për të llogaritur një element të ri.

l_int1 = [1, 2, 3]
l_int2 = [10, 20, 30]

l_sub = [i2 - i1 for i1, i2 in zip(l_int1, l_int2)]
print(l_sub)
# [9, 18, 27]

shënimi i përfshirjes së listës së mbivendosur

Ashtu si foleja për sythe, shënimi i të kuptuarit të listës gjithashtu mund të jetë i ndërthurur.

[Expression for Variable Name 1 in Iterable Object 1
    for Variable Name 2 in Iterable Object 2
        for Variable Name 3 in Iterable Object 3 ... ]

Për lehtësi, janë shtuar ndërprerjet dhe dhëmbëzimi i rreshtave, por nuk kërkohen për gramatikën; ato mund të vazhdohen në një rresht të vetëm.

Një shembull është dhënë së bashku me një ekuivalent për deklaratë.

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

flat = [x for row in matrix for x in row]
print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
flat = []
for row in matrix:
    for x in row:
        flat.append(x)

print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

Është gjithashtu e mundur të përdoren variabla të shumta.

cells = [(row, col) for row in range(3) for col in range(2)]
print(cells)
# [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]

Ju gjithashtu mund të bëni degëzim të kushtëzuar.

cells = [(row, col) for row in range(3)
         for col in range(2) if col == row]
print(cells)
# [(0, 0), (1, 1)]

Është gjithashtu e mundur të degëzohet me kusht për çdo objekt iterable.

cells = [(row, col) for row in range(3) if row % 2 == 0
         for col in range(2) if col % 2 == 0]
print(cells)
# [(0, 0), (2, 0)]

vendos shënimin e përfshirjes(Set comprehensions)

Ndryshimi i kllapave katrore [] në shënimin e kuptimit të listës në kllapa kaçurrelë {} krijon një grup (objekt i tipit grup).

{Expression for Any Variable Name in Iterable Object}
s = {i**2 for i in range(5)}

print(s)
# {0, 1, 4, 9, 16}

shënimi i përfshirjes së fjalorit(Dict comprehensions)

Fjalorët (objektet e tipit dikt) gjithashtu mund të gjenerohen me shënime të të kuptuarit.

{}, dhe specifikoni çelësin dhe vlerën në pjesën e shprehjes si çelës: vlerë.

{Key: Value for Any Variable Name in Iterable Object}

Çdo shprehje mund të specifikohet për çelësin dhe vlerën.

l = ['Alice', 'Bob', 'Charlie']

d = {s: len(s) for s in l}
print(d)
# {'Alice': 5, 'Bob': 3, 'Charlie': 7}

Për të krijuar një fjalor të ri nga një listë çelësash dhe vlerash, përdorni funksionin zip().

keys = ['k1', 'k2', 'k3']
values = [1, 2, 3]

d = {k: v for k, v in zip(keys, values)}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}

lloji i gjeneratorit(Generator expressions)

Nëse kllapat katrore [] në shënimin e kuptimit të listës përdoren si kllapa të rrumbullakëta (), në vend të një tupleje kthehet një gjenerator. Kjo quhet shprehje gjenerator.

Shembull i shënimit të kuptimit të listës.

l = [i**2 for i in range(5)]

print(l)
# [0, 1, 4, 9, 16]

print(type(l))
# <class 'list'>

Shembull i një shprehje gjeneratori. Nëse e printoni () gjeneratorin ashtu siç është, ai nuk do të printojë përmbajtjen e tij, por nëse e përdorni me një deklaratë for, mund të merrni përmbajtjen.

g = (i**2 for i in range(5))

print(g)
# <generator object <genexpr> at 0x10af944f8>

print(type(g))
# <class 'generator'>

for i in g:
    print(i)
# 0
# 1
# 4
# 9
# 16

Shprehjet e gjeneratorit gjithashtu lejojnë degëzim me kusht dhe fole duke përdorur if si dhe shënimin e kuptimit të listës.

g_cells = ((row, col) for row in range(0, 3)
           for col in range(0, 2) if col == row)

print(type(g_cells))
# <class 'generator'>

for i in g_cells:
    print(i)
# (0, 0)
# (1, 1)

Për shembull, nëse një listë me një numër të madh elementësh krijohet duke përdorur shënimin e kuptimit të listës dhe më pas hapet me një deklaratë for, lista që përmban të gjithë elementët do të gjenerohet në fillim nëse përdoret shënimi i kuptimit të listës. Nga ana tjetër, nëse përdorni një shprehje gjenerator, sa herë që përsëritet cikli, elementët gjenerohen një nga një, duke zvogëluar kështu sasinë e memories së përdorur.

Nëse shprehja e gjeneratorit është argumenti i vetëm i funksionit, kllapat e rrumbullakëta () mund të hiqen.

print(sum([i**2 for i in range(5)]))
# 30

print(sum((i**2 for i in range(5))))
# 30

print(sum(i**2 for i in range(5)))
# 30

Sa i përket shpejtësisë së përpunimit, shënimi i të kuptuarit të listës është shpesh më i shpejtë se shënimi i gjeneratorit kur të gjithë elementët përpunohen.

Megjithatë, kur gjykojmë me all() ose any(), për shembull, rezultati përcaktohet kur është i pranishëm false ose true, kështu që përdorimi i shprehjeve të gjeneratorit mund të jetë më i shpejtë se përdorimi i shënimit të kuptimit të listës.

Nuk ka shënim kuptimi tuple, por nëse përdorni një shprehje gjenerator si argument të tuple(), mund të gjeneroni një tuple në shënimin e kuptimit.

t = tuple(i**2 for i in range(5))

print(t)
# (0, 1, 4, 9, 16)

print(type(t))
# <class 'tuple'>
Copied title and URL