Í Python er einfalt að nota listaskilning þegar búið er til nýjan lista.(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
Í þessari grein munum við fyrst ræða eftirfarandi
- Grunngerð listaskilnings
- Listaskilningur með skilyrtri greiningu eftir ef
- Samsetning með þrískiptingum (ef annað eins vinnsla)
zip()
,enumerate()
Samsetning með þessum- tákn fyrir innlimun á hreiðri lista
Næst munum við útskýra mengið af listaskilningi með sýnishornskóða.
- stilltu skráningarmerki(
Set comprehensions
) - orðabók innlimun nótnaskrift(
Dict comprehensions
) - rafall gerð(
Generator expressions
)
- Grunngerð listaskilnings
- Listaskilningur með skilyrtri greiningu eftir ef
- Samsetning með þrískiptingum (ef annað eins vinnsla)
- Samsetning með zip() og enumerate()
- tákn fyrir innlimun á hreiðri lista
- stilltu skráningarmerki(Set comprehensions)
- orðabók innlimun nótnaskrift(Dict comprehensions)
- rafall gerð(Generator expressions)
Grunngerð listaskilnings
Listaskilningurinn er skrifaður sem hér segir.
[Expression for Any Variable Name in Iterable Object]
Það tekur hvern þátt í endurteknum hlut eins og lista, tuple eða svið eftir handahófskenndu breytuheiti og metur það með tjáningu. Nýr listi með matsniðurstöðu sem þátt er skilað.
Dæmi er gefið ásamt jafngildi fyrir staðhæfingu.
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]
Sama ferli er hægt að gera með map(), en listaskilningurinn er valinn vegna einfaldleika og skýrleika.
Listaskilningur með skilyrtri greiningu eftir ef
Skilyrt greiningar með ef er líka mögulegt. Skrifaðu ef í postfix sem hér segir.
[Expression for Any Variable Name in Iterable Object if Conditional Expression]
Einungis þættir endurtekjanlega hlutans þar sem skilyrt tjáning er sönn eru metin af tjáningunni og nýr listi með þætti sem eru afleiðingin er skilað.
Þú getur notað hvaða breytuheiti sem er í skilyrtu tjáningu.
Dæmi er gefið ásamt jafngildi fyrir staðhæfingu.
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]
Sama ferli er hægt að gera með filter(), en listaskilningurinn er valinn vegna einfaldleika og skýrleika.
Samsetning með þrískiptingum (ef annað eins vinnsla)
Í dæminu hér að ofan eru aðeins þeir þættir sem uppfylla skilyrðin unnar og þeir sem uppfylla ekki skilyrðin eru útilokaðir frá nýja listanum.
Ef þú vilt skipta um ferlið eftir aðstæðum, eða ef þú vilt vinna úr þætti sem uppfylla ekki skilyrðið öðruvísi, eins og ef annað, notaðu þrískiptinguna.
Í Python er hægt að skrifa þrískiptinguna sem hér segir
Value When True if Conditional Expression else Value When False
Þetta er notað í tjáningarhluta listaskilningsins eins og sýnt er hér að neðan.
[Value When True if Conditional Expression else Value When False for Any Variable Name in Iterable Object]
Dæmi er gefið ásamt jafngildi fyrir staðhæfingu.
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']
Það er líka hægt að skrifa segð með því að nota handahófskenndar breytuheiti fyrir sönn og ósönn gildi.
Ef skilyrðið er fullnægt er einhver vinnsla gerð, annars er gildi upprunalega endurtekjanlega hlutarins óbreytt.
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]
Samsetning með zip() og enumerate()
Gagnlegar aðgerðir sem eru oft notaðar í for yfirlýsingunni eru zip(), sem sameinar margar endurtekningar, og enumerate(), sem skilar gildi ásamt vísitölu þess.
Auðvitað er hægt að nota zip() og enumerate() með listaskilningi. Það er ekki sérstök setningafræði og það er ekki erfitt ef þú lítur á samsvörunina við for-yfirlýsinguna.
Dæmi um 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')]
Dæmi um 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')]
Hugmyndin er sú sama og áður þegar þú notar 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')]
Hvert stak er einnig hægt að nota til að reikna út nýtt stak.
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]
tákn fyrir innlimun á hreiðri lista
Eins og hreiður fyrir lykkjur, er einnig hægt að hreiðra listaskilning.
[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 ... ]
Til hægðarauka hefur verið bætt við línuskilum og inndráttum, en eru ekki nauðsynlegar fyrir málfræði; hægt er að halda þeim áfram á einni línu.
Dæmi er gefið ásamt jafngildi fyrir staðhæfingu.
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]
Það er líka hægt að nota margar breytur.
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)]
Þú getur líka gert skilyrta greiningu.
cells = [(row, col) for row in range(3)
for col in range(2) if col == row]
print(cells)
# [(0, 0), (1, 1)]
Það er líka hægt að skilyrta grein fyrir hvern endurtekanlegan hlut.
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)]
stilltu skráningarmerki(Set comprehensions)
Með því að breyta hornklofa [] í listaskilningi yfir í krullaða sviga {} verður til mengi (hlutur úr mengi).
{Expression for Any Variable Name in Iterable Object}
s = {i**2 for i in range(5)}
print(s)
# {0, 1, 4, 9, 16}
orðabók innlimun nótnaskrift(Dict comprehensions)
Einnig er hægt að búa til orðabækur (hlutir af dict type) með skilningsnátnun.
{} og tilgreindu lykilinn og gildið í tjáningarhlutanum sem lykill: gildi.
{Key: Value for Any Variable Name in Iterable Object}
Hægt er að tilgreina hvaða tjáningu sem er fyrir lykil og gildi.
l = ['Alice', 'Bob', 'Charlie']
d = {s: len(s) for s in l}
print(d)
# {'Alice': 5, 'Bob': 3, 'Charlie': 7}
Til að búa til nýja orðabók úr lista yfir lykla og gildi, notaðu zip() aðgerðina.
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}
rafall gerð(Generator expressions)
Ef hornklofa [] í listaskilningi eru notaðir sem hringsvigar (), er rafall skilað í stað tupels. Þetta er kallað rafallatjáning.
Dæmi um listaskilning.
l = [i**2 for i in range(5)]
print(l)
# [0, 1, 4, 9, 16]
print(type(l))
# <class 'list'>
Dæmi um tjáningu rafall. Ef þú prentar() rafallinn eins og hann er mun hann ekki prenta út innihald hans, en ef þú keyrir hann með for-yfirlýsingu geturðu fengið innihaldið.
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
Rafallatjáningar leyfa einnig skilyrta greiningu og hreiður með því að nota if sem og listaskilning.
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)
Til dæmis, ef listi með miklum fjölda þátta er búinn til með því að nota listaskilning nótnaskrift og síðan er sleginn í gegnum lykkju með for setningu, verður listinn sem inniheldur alla þættina myndaður í upphafi ef listaskilningur er notaður. Á hinn bóginn, ef þú notar rafallatjáningu, í hvert skipti sem lykkjan er endurtekin, eru þættirnir búnir til einn af öðrum, þannig að minnismagnið sem notað er minnkar.
Ef rafallatjáningin er einu rök fallsins er hægt að sleppa hringlaga svigunum ().
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
Hvað varðar vinnsluhraða, þá er listaskilningurinn oft hraðari en rafalansnátan þegar allir þættir eru unnar.
Hins vegar, þegar dæmt er með all() eða any(), til dæmis, er niðurstaðan ákvörðuð þegar rangt eða satt er til staðar, þannig að notkun rafallatjáa gæti verið hraðari en að nota listaskilning.
Það er engin túlluskilningstákn, en ef þú notar rafallatjáningu sem rök fyrir tuple(), geturðu búið til tuple í skilningsnátanum.
t = tuple(i**2 for i in range(5))
print(t)
# (0, 1, 4, 9, 16)
print(type(t))
# <class 'tuple'>