Katika Python, ni rahisi kutumia nukuu ya ufahamu wa orodha wakati wa kutoa orodha mpya.(List comprehensions
)
- 5. Data Structures — List Comprehensions — Python 3.10.0 Documentation
- 6. Expressions — Displays for lists, sets and dictionaries — Python 3.10.0 Documentation
Katika makala hii, tutazungumzia kwanza mambo yafuatayo
- Aina ya msingi ya nukuu ya ufahamu wa orodha
- Orodhesha nukuu ya ufahamu yenye matawi ya masharti kwa if
- Mchanganyiko na waendeshaji wa ternary (ikiwa usindikaji mwingine kama huo)
zip()
,enumerate()
Mchanganyiko na haya- nukuu ya ujumuishaji wa orodha iliyoorodheshwa
Ifuatayo, tutaelezea seti ya nukuu za ufahamu wa orodha na msimbo wa sampuli.
- weka nukuu ya kujumuisha(
Set comprehensions
) - nukuu ya ujumuishaji wa kamusi(
Dict comprehensions
) - aina ya jenereta(
Generator expressions
)
- Aina ya msingi ya nukuu ya ufahamu wa orodha
- Orodhesha nukuu ya ufahamu yenye matawi ya masharti kwa if
- Mchanganyiko na waendeshaji wa ternary (ikiwa usindikaji mwingine kama huo)
- Mchanganyiko na zip() na enumerate()
- nukuu ya ujumuishaji wa orodha iliyoorodheshwa
- weka nukuu ya kujumuisha(Set comprehensions)
- nukuu ya ujumuishaji wa kamusi(Dict comprehensions)
- aina ya jenereta(Generator expressions)
Aina ya msingi ya nukuu ya ufahamu wa orodha
Alama ya ufahamu wa orodha imeandikwa kama ifuatavyo.
[Expression for Any Variable Name in Iterable Object]
Inachukua kila kipengele cha kitu kinachoweza kutekelezeka kama vile orodha, tuple, au safu kwa jina tofauti kiholela na kukitathmini kwa usemi. Orodha mpya yenye matokeo ya tathmini kama kipengele inarejeshwa.
Mfano unatolewa pamoja na sawa na taarifa.
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]
Mchakato sawa unaweza kufanywa na map(), lakini nukuu ya ufahamu wa orodha inapendekezwa kwa urahisi na uwazi wake.
Orodhesha nukuu ya ufahamu yenye matawi ya masharti kwa if
Matawi ya masharti na ikiwa inawezekana pia. Andika if kwenye postfix kama ifuatavyo.
[Expression for Any Variable Name in Iterable Object if Conditional Expression]
Vipengele vya kitu kinachoweza kutekelezeka pekee ambacho usemi wake wa masharti ni kweli ndivyo hutathminiwa kwa usemi, na orodha mpya ambayo vipengele vyake ni matokeo hurejeshwa.
Unaweza kutumia jina lolote la kutofautisha katika usemi wa masharti.
Mfano unatolewa pamoja na sawa na taarifa.
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]
Mchakato sawa unaweza kufanywa na chujio (), lakini nukuu ya ufahamu wa orodha inapendekezwa kwa urahisi na uwazi wake.
Mchanganyiko na waendeshaji wa ternary (ikiwa usindikaji mwingine kama huo)
Katika mfano hapo juu, vipengele tu vinavyokidhi vigezo vinashughulikiwa, na wale ambao hawakidhi vigezo hutolewa kwenye orodha mpya.
Ikiwa unataka kubadilisha mchakato kulingana na hali, au ikiwa unataka kusindika vitu ambavyo havikidhi hali hiyo kwa njia tofauti, kama vile vinginevyo, tumia opereta wa ternary.
Katika Python, operator ternary inaweza kuandikwa kama ifuatavyo
Value When True if Conditional Expression else Value When False
Hii inatumika katika sehemu ya usemi ya nukuu ya ufahamu wa orodha kama inavyoonyeshwa hapa chini.
[Value When True if Conditional Expression else Value When False for Any Variable Name in Iterable Object]
Mfano unatolewa pamoja na sawa na taarifa.
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']
Inawezekana pia kuandika misemo kwa kutumia majina tofauti ya kiholela kwa maadili ya kweli na ya uwongo.
Ikiwa hali imeridhika, usindikaji fulani unafanywa, vinginevyo thamani ya kitu cha awali iterable imesalia bila kubadilika.
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]
Mchanganyiko na zip() na enumerate()
Chaguo za kukokotoa ambazo hutumiwa mara kwa mara katika taarifa ni pamoja na zip(), ambayo inachanganya maandishi mengi, na enumerate(), ambayo hurejesha thamani pamoja na faharasa yake.
Kwa kweli, inawezekana kutumia zip() na enumerate() na nukuu ya ufahamu wa orodha. Sio syntax maalum, na sio ngumu ikiwa utazingatia mawasiliano na kwa taarifa.
Mfano wa 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')]
Mfano wa 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')]
Wazo ni sawa na hapo awali wakati wa kutumia 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')]
Kila kipengele kinaweza pia kutumika kukokotoa kipengele kipya.
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]
nukuu ya ujumuishaji wa orodha iliyoorodheshwa
Kama vile kuweka viota kwa vitanzi, nukuu ya ufahamu wa orodha pia inaweza kuwekwa.
[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 ... ]
Kwa urahisi, mapumziko ya mstari na indentations zimeongezwa, lakini hazihitajiki kwa sarufi; zinaweza kuendelezwa kwa mstari mmoja.
Mfano unatolewa pamoja na sawa na taarifa.
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]
Inawezekana pia kutumia vigezo vingi.
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)]
Unaweza pia kufanya matawi ya masharti.
cells = [(row, col) for row in range(3)
for col in range(2) if col == row]
print(cells)
# [(0, 0), (1, 1)]
Inawezekana pia kuweka tawi kwa kila kitu kinachoweza kutekelezeka.
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)]
weka nukuu ya kujumuisha(Set comprehensions)
Kubadilisha mabano ya mraba [] katika nukuu ya ufahamu wa orodha hadi mabano yaliyojipinda {} huunda seti (kitu cha aina).
{Expression for Any Variable Name in Iterable Object}
s = {i**2 for i in range(5)}
print(s)
# {0, 1, 4, 9, 16}
nukuu ya ujumuishaji wa kamusi(Dict comprehensions)
Kamusi (vitu vya aina ya dict) pia vinaweza kutolewa kwa nukuu ya ufahamu.
{}, na ubainishe ufunguo na thamani katika sehemu ya usemi kama ufunguo: thamani.
{Key: Value for Any Variable Name in Iterable Object}
Usemi wowote unaweza kubainishwa kwa ufunguo na thamani.
l = ['Alice', 'Bob', 'Charlie']
d = {s: len(s) for s in l}
print(d)
# {'Alice': 5, 'Bob': 3, 'Charlie': 7}
Ili kuunda kamusi mpya kutoka kwa orodha ya vitufe na thamani, tumia zip() chaguo la kukokotoa.
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}
aina ya jenereta(Generator expressions)
Ikiwa mabano ya mraba [] katika nukuu ya ufahamu wa orodha yanatumiwa kama mabano ya duara (), jenereta inarudishwa badala ya nakala. Hii inaitwa maneno ya jenereta.
Mfano wa nukuu ya ufahamu wa orodha.
l = [i**2 for i in range(5)]
print(l)
# [0, 1, 4, 9, 16]
print(type(l))
# <class 'list'>
Mfano wa usemi wa jenereta. Ukichapisha () jenereta jinsi ilivyo, haitachapisha yaliyomo, lakini ikiwa utaiendesha na kwa taarifa, unaweza kupata yaliyomo.
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
Semi za jenereta pia huruhusu kuweka matawi kwa masharti na kuweka kiota kwa kutumia ikiwa na vile vile nukuu ya ufahamu wa orodha.
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)
Kwa mfano, ikiwa orodha yenye idadi kubwa ya vipengele inatolewa kwa kutumia nukuu ya ufahamu wa orodha na kisha kuunganishwa na kwa taarifa, orodha iliyo na vipengele vyote itatolewa mwanzoni ikiwa nukuu ya ufahamu wa orodha itatumika. Kwa upande mwingine, ikiwa unatumia kujieleza kwa jenereta, kila wakati kitanzi kinarudiwa, vipengele vinazalishwa moja kwa moja, hivyo kupunguza kiasi cha kumbukumbu inayotumiwa.
Ikiwa usemi wa jenereta ndio hoja pekee ya chaguo la kukokotoa, mabano ya pande zote () yanaweza kuachwa.
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
Kuhusu kasi ya uchakataji, nukuu ya ufahamu wa orodha mara nyingi huwa haraka kuliko nukuu ya jenereta wakati vipengele vyote vinachakatwa.
Hata hivyo, wakati wa kuhukumu na all() au any(), kwa mfano, matokeo hubainishwa wakati uongo au kweli upo, kwa hivyo kutumia vielezi vya jenereta kunaweza kuwa haraka kuliko kutumia nukuu ya ufahamu wa orodha.
Hakuna nukuu ya ufahamu wa tuple, lakini ukitumia usemi wa jenereta kama hoja ya tuple(), unaweza kutoa nakala katika nukuu ya ufahamu.
t = tuple(i**2 for i in range(5))
print(t)
# (0, 1, 4, 9, 16)
print(type(t))
# <class 'tuple'>