Paggamit ng Python list comprehension notation

Negosyo

Sa Python, madaling gamitin ang notasyon ng mga pag-unawa sa listahan kapag bumubuo ng bagong listahan.(List comprehensions)

Sa artikulong ito, tatalakayin muna natin ang mga sumusunod

  • Pangunahing uri ng notasyon sa pag-unawa sa listahan
  • Ilista ang notasyon ng pang-unawa na may conditional branching sa pamamagitan ng kung
  • Kumbinasyon sa mga ternary operator (kung iba ang pagpoproseso)
  • zip(),enumerate()Kumbinasyon sa mga ito
  • nested list inclusion notation

Susunod, ipapaliwanag namin ang hanay ng notasyon sa pag-unawa sa listahan na may sample code.

  • itakda ang inclusion notation(Set comprehensions)
  • notasyon ng pagsasama ng diksyunaryo(Dict comprehensions)
  • uri ng generator(Generator expressions)

Pangunahing uri ng notasyon sa pag-unawa sa listahan

Ang notasyon sa pag-unawa sa listahan ay nakasulat tulad ng sumusunod.

[Expression for Any Variable Name in Iterable Object]

Kinukuha nito ang bawat elemento ng isang iterable object tulad ng isang listahan, tuple, o range sa pamamagitan ng isang arbitrary na pangalan ng variable at sinusuri ito gamit ang isang expression. Ang isang bagong listahan na may resulta ng pagsusuri bilang isang elemento ay ibinalik.

Ang isang halimbawa ay ibinigay kasama ng isang katumbas para sa pahayag.

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]

Ang parehong proseso ay maaaring gawin sa map(), ngunit ang listahan ng pag-unawa sa notasyon ay ginustong para sa pagiging simple at kalinawan nito.

Ilista ang notasyon ng pang-unawa na may conditional branching sa pamamagitan ng kung

Conditional branching na kung pwede rin. Isulat ang kung sa postfix gaya ng sumusunod.

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

Tanging ang mga elemento ng iterable object na ang conditional expression ay totoo ang sinusuri ng expression, at isang bagong listahan na ang mga elemento ay ang resulta ay ibinalik.

Maaari mong gamitin ang anumang variable na pangalan sa conditional expression.

Ang isang halimbawa ay ibinigay kasama ng isang katumbas para sa pahayag.

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]

Ang parehong proseso ay maaaring gawin sa filter(), ngunit ang listahan ng pag-unawa sa notasyon ay ginustong para sa pagiging simple at kalinawan nito.

Kumbinasyon sa mga ternary operator (kung iba ang pagpoproseso)

Sa halimbawa sa itaas, ang mga elemento lamang na nakakatugon sa pamantayan ang pinoproseso, at ang mga hindi nakakatugon sa pamantayan ay hindi kasama sa bagong listahan.

Kung gusto mong ilipat ang proseso depende sa kundisyon, o kung gusto mong iproseso ang mga elemento na hindi nakakatugon sa kundisyon sa ibang paraan, na parang iba, gamitin ang ternary operator.

Sa Python, ang ternary operator ay maaaring isulat bilang mga sumusunod

Value When True if Conditional Expression else Value When False

Ginagamit ito sa bahagi ng expression ng notasyon sa pag-unawa sa listahan tulad ng ipinapakita sa ibaba.

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

Ang isang halimbawa ay ibinigay kasama ng isang katumbas para sa pahayag.

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']

Posible rin na magsulat ng mga expression gamit ang mga arbitrary na pangalan ng variable para sa true at false na mga halaga.

Kung ang kundisyon ay nasiyahan, ang ilang pagproseso ay tapos na, kung hindi, ang halaga ng orihinal na iterable na bagay ay hindi nababago.

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]

Kumbinasyon sa zip() at enumerate()

Ang mga kapaki-pakinabang na function na kadalasang ginagamit sa for statement ay kinabibilangan ng zip(), na pinagsasama ang maraming iterable, at enumerate(), na nagbabalik ng value kasama ng index nito.

Siyempre, posibleng gumamit ng zip() at enumerate() na may notasyon sa pag-unawa sa listahan. Ito ay hindi isang espesyal na syntax, at hindi mahirap kung isasaalang-alang mo ang pagsusulatan sa para sa pahayag.

Halimbawa ng 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')]

Halimbawa ng 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')]

Ang ideya ay kapareho ng dati kapag gumagamit ng 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')]

Ang bawat elemento ay maaari ding gamitin upang kalkulahin ang isang bagong elemento.

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]

nested list inclusion notation

Tulad ng nesting para sa mga loop, maaari ding i-nest ang notation ng pag-unawa sa listahan.

[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 ... ]

Para sa kaginhawahan, idinagdag ang mga line break at indentation, ngunit hindi kinakailangan para sa grammar; maaari silang ipagpatuloy sa isang linya.

Ang isang halimbawa ay ibinigay kasama ng isang katumbas para sa pahayag.

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]

Posible ring gumamit ng maramihang mga variable.

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

Maaari ka ring magsagawa ng conditional branching.

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

Posible rin na may kondisyon na magsanga para sa bawat iterable na bagay.

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

itakda ang inclusion notation(Set comprehensions)

Ang pagpapalit ng mga square bracket [] sa notasyon ng pang-unawa sa listahan sa mga kulot na bracket {} ay lumilikha ng isang set (set-type na object).

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

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

notasyon ng pagsasama ng diksyunaryo(Dict comprehensions)

Ang mga diksyunaryo (mga bagay na uri ng dict) ay maaari ding mabuo gamit ang notasyon ng pang-unawa.

{}, at tukuyin ang key at value sa bahagi ng expression bilang key: value.

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

Maaaring tukuyin ang anumang expression para sa susi at halaga.

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

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

Upang lumikha ng bagong diksyunaryo mula sa isang listahan ng mga key at value, gamitin ang zip() function.

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}

uri ng generator(Generator expressions)

Kung ang mga square bracket [] sa notasyon ng mga pang-unawa sa listahan ay ginagamit bilang mga round bracket (), isang generator ang ibabalik sa halip na isang tuple. Ito ay tinatawag na generator expression.

Halimbawa ng list comprehension notation.

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

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

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

Halimbawa ng expression ng generator. Kung i-print mo () ang generator kung ano ito, hindi nito ipi-print ang mga nilalaman nito, ngunit kung patakbuhin mo ito gamit ang isang for statement, maaari mong makuha ang mga nilalaman.

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

Pinapayagan din ng mga generator expression ang conditional branching at nesting gamit ang if pati na rin ang list comprehension notation.

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)

Halimbawa, kung ang isang listahan na may malaking bilang ng mga elemento ay nabuo gamit ang list comprehension notation at pagkatapos ay i-loop sa pamamagitan ng isang for statement, ang listahan na naglalaman ng lahat ng mga elemento ay bubuo sa simula kung ang listahan ng comprehension notation ay gagamitin. Sa kabilang banda, kung gagamit ka ng generator expression, sa tuwing inuulit ang loop, ang mga elemento ay nabuo nang paisa-isa, kaya binabawasan ang dami ng memory na ginamit.

Kung ang expression ng generator ay ang tanging argumento ng function, ang mga round bracket () ay maaaring tanggalin.

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

Tulad ng para sa bilis ng pagproseso, ang notasyon sa pag-unawa sa listahan ay kadalasang mas mabilis kaysa sa notasyon ng generator kapag naproseso ang lahat ng elemento.

Gayunpaman, kapag hinuhusgahan ang lahat() o alinmang(), halimbawa, ang resulta ay tinutukoy kapag mali o totoo ang naroroon, kaya ang paggamit ng mga expression ng generator ay maaaring mas mabilis kaysa sa paggamit ng notasyon sa pag-unawa sa listahan.

Walang tuple comprehension notation, ngunit kung gagamit ka ng generator expression bilang argumento ng tuple(), maaari kang bumuo ng tuple sa comprehension notation.

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

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

print(type(t))
# <class 'tuple'>