Ачааллж байна...
Курс 1-д та хэдэн арван удаа нэг ижил хэв маягийн код бичсэн. Хоосон list үүсгэнэ, дараа нь loop ажиллуулна, loop бүрд ямар нэг зүйл тооцоолж append хийнэ, эцэст нь дүүрсэн list-ээ ашиглана. Тэр хэв маяг ажилладаг, зөв, ойлгомжтой — бид түүнийг буруутгахгүй. Гэвч Python-д яг энэ хэв маягийг илүү богино, илүү тод илэрхийлэх тусгай бичлэг байдаг бөгөөд түүнийг list comprehension гэж нэрлэдэг. Энэ нэр томьёог англиар нь хэвээр хэрэглэнэ, учир нь та documentation болон бусад хүмүүсийн кодод яг ийм үгээр л уулзана.
List comprehension бол шинэ чадвар биш. Тэр танд өмнө нь хийж чадахгүй байсан ямар ч зүйлийг өгөхгүй. Тэр зөвхөн танд нэгэнт байгаа чадварыг илүү тод илэрхийлэх арга өгдөг. Энэ бол чухал ялгаа: бид энд хүчийг нь биш, ТОДОРХОЙ БАЙДЛЫГ нь дээшлүүлж байна. Мэргэжлийн Python код унших үед та comprehension-ыг хаа сайгүй харах болно, тиймээс түүнийг унших чадвар нь бичих чадвараас багагүй чухал. Энэ хичээлийн зорилго бол та comprehension-ыг хараад "энэ юу хийж байна вэ" гэж толгойдоо шууд хөрвүүлж чаддаг болох явдал.
Ресторанд орлоо гэж төсөөлье. Та зөөгчид ингэж хэлж болно: "Эхлээд хоосон тавиур ав. Дараа нь цэс дээрх хоол бүрийг ээлжлэн үз. Хоол бүрийг харахдаа түүнийг чинаад тавиур дээрээ нэм. Цэс дуусахад тавиураа надад авчир." Энэ заавар бүрэн зөв, зөөгч түүнийг гүйцэтгэж чадна. Гэхдээ хэн ч ингэж захиалдаггүй.
Бодит амьдрал дээр та ингэж хэлнэ: "Цэсэн дээрх бүх хоолыг чанаж авчирна уу." Нэг өгүүлбэр. Ижил үр дүн. Зөөгч дотроо яг тэр алхмуудыг л хийнэ, гэхдээ та тэдгээрийг нэг бүрчлэн тоочих шаардлагагүй болсон.
List comprehension бол яг энэ хоёр дахь өгүүлбэр юм. Та Python-д "хоосон list ав, loop хий, append хий" гэж алхам алхмаар зааварлахын оронд, "энэ жагсаалтын элемент бүрээс ийм зүйл гаргаад надад шинэ жагсаалт өг" гэж НЭГ өгүүлбэрээр захиална. Дотор нь ижил loop ажиллана — Python түүнийг таны өмнөөс хийж байгаа. Ялгаа нь зөвхөн та юуг илэрхийлж байгаад л оршино: алхмуудыг биш, ЗОРИЛГОО.
Эхлээд танил кодоос эхэлье. Бидэнд тоонуудын list байна, тэдгээрийн квадратыг агуулсан шинэ list үүсгэхийг хүсэж байна.
python
tootsuud = [1, 2, 3, 4, 5]
kvadratuud = []
for too in tootsuud:
kvadratuud.append(too * too)
print(kvadratuud)Энэ кодыг мөр мөрөөр нь уншъя. Эхний мөрөнд бид tootsuud нэртэй list үүсгэж, дотор нь таван тоо хийсэн. Гурав дахь мөрөнд kvadratuud нэртэй ХООСОН list үүсгэсэн — энэ бол хоосон тавиур, бид түүнийг дүүргэх гэж байна. Дөрөв дэх мөрөнд for loop эхэлж, tootsuud доторх элемент бүрийг ээлжлэн too хувьсагчид хийж байна. Тав дахь мөрөнд тухайн тоог өөрөөрөө үржүүлж (өөрөөр хэлбэл квадрат болгож) үр дүнг kvadratuud жагсаалтад append буюу нэмж байна. Loop дуусахад kvadratuud дүүрсэн байна.
Хэвлэгдэх үр дүн:
[1, 4, 9, 16, 25]Энэ код бүрэн зөв. Ямар ч буруу зүйл алга. Гэхдээ анзаараарай: таван мөрийн гурав нь зөвхөн "механик" ажил хийж байна — хоосон list үүсгэх, loop эргүүлэх, append хийх. Жинхэнэ санаа буюу too * too гэдэг нь ганцхан газар л байна. Comprehension нь тэр механик хэсгийг нуугаад, санааг нь урд гаргаж ирдэг.
Одоо яг ижил үр дүнг comprehension-оор бичье:
python
tootsuud = [1, 2, 3, 4, 5]
kvadratuud = [too * too for too in tootsuud]
print(kvadratuud)Хэвлэгдэх үр дүн яг ижил:
[1, 4, 9, 16, 25]Энэ хоёр дахь мөрийг маш анхааралтай задалъя, учир нь энэ бол бүхэл хичээлийн зүрх юм.
Хамгийн гадна талд нь дөрвөлжин хаалт [ ] байгааг анзаараарай. Энэ хаалт нь "энд list үүснэ" гэж хэлж байна — яг л та [1, 2, 3] гэж list бичихэд ашигладаг хаалт. Тэгэхээр эхний мэдээлэл: үр дүн нь list байх болно.
Хаалт дотор хоёр хэсэг байна. Баруун талын хэсэг нь for too in tootsuud — энэ бол таны танил loop-ийн толгой мөр, яг тэр л үгсээр, яг тэр л дарааллаар. Тэр нь "tootsuud доторх элемент бүрийг ээлжлэн авч, too гэж нэрлэ" гэсэн утгатай.
Зүүн талын хэсэг нь too * too — энэ бол элемент бүрээс ЮУ ГАРГАХ вэ гэдэг заавар. Loop эргэх бүрд Python энэ илэрхийллийг тооцоолж, гарсан утгыг шинэ list-д автоматаар нэмнэ. append бичих шаардлагагүй, Python түүнийг өөрөө хийнэ.
Уншихдаа энэ дарааллыг санаарай: эхлээд баруун талыг, дараа нь зүүн талыг унш. Өөрөөр хэлбэл "tootsuud доторх too бүрийн хувьд — too үржих too гарга." Хүн төрөлхтний бодох дараалал ийм байдаг ч Python бичлэгийг эсрэгээр нь тавьсан нь эхэндээ хачирхалтай санагдаж болно. Хэдэн жишээ уншсаны дараа энэ нь хэвшинэ.
Comprehension зөвхөн тоонд зориулагдаагүй. Курс 1-ийн харилцагчийн дэвтрийг санаж байна уу? Тэнд нэрсийн жагсаалт байсан. Одоо тэдгээрийг том үсгээр бичсэн шинэ жагсаалт үүсгэе.
Эхлээд танил аргаар:
python
nerууd = ["болд", "сараа", "төмөр", "цэцэг"]
tomooor = []
for ner in nerууd:
tomooor.append(ner.upper())
print(tomooor)Одоо comprehension-оор:
python
nerууd = ["болд", "сараа", "төмөр", "цэцэг"]
tomooor = [ner.upper() for ner in nerууd]
print(tomooor)Хоёулаа ижил үр дүн өгнө:
['БОЛД', 'САРАА', 'ТӨМӨР', 'ЦЭЦЭГ']Энд ner.upper() бол Курс 1-ээс танил string-ийн method — тэр нь string-ийг том үсэг рүү хөрвүүлж, ШИНЭ string буцаадаг (анхны string-ээ өөрчилдөггүй). Comprehension дотор та ямар ч илэрхийлэл, ямар ч method дуудалт, ямар ч тооцоолол бичиж болно. Гол дүрэм ганцхан: тэр илэрхийлэл ямар нэг УТГА буцаадаг байх ёстой, учир нь тэр утга шинэ list-д орох гэж байгаа юм.
Одоо илүү хүчирхэг зүйл рүү орно. Ихэнхдээ бид бүх элементийг биш, зөвхөн ТОДОРХОЙ НӨХЦӨЛД тохирсон элементүүдийг л сонгож авахыг хүсдэг.
Танил аргаар — тэгш тоонуудыг л сонгож авъя:
python
tootsuud = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
tegsh = []
for too in tootsuud:
if too % 2 == 0:
tegsh.append(too)
print(tegsh)Энэ кодод Курс 1-ийн % (modulo) оператор ажиллаж байна: too % 2 нь тухайн тоог 2-т хуваахад үлдэх үлдэгдлийг өгдөг. Хэрэв үлдэгдэл нь 0 бол тоо тэгш гэсэн үг. Loop бүрд бид энэ нөхцөлийг шалгаж, зөвхөн үнэн байвал append хийж байна.
Одоо comprehension-оор:
python
tootsuud = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
tegsh = [too for too in tootsuud if too % 2 == 0]
print(tegsh)Үр дүн:
[2, 4, 6, 8, 10]Энд ГУРАВ дахь хэсэг нэмэгдлээ: if too % 2 == 0. Тэр нь comprehension-ы хамгийн төгсгөлд, for хэсгийн ард орж байна. Утга нь энгийн: "loop эргэх бүрд эхлээд энэ нөхцөлийг шалга. Хэрэв худал бол энэ элементийг БҮРЭН АЛГАСА, шинэ list-д юу ч бүү нэм. Хэрэв үнэн бол зүүн талын илэрхийллийг тооцоолж нэм."
Уншлагын дараалал одоо ийм болно: for → if → зүүн тал. Өөрөөр хэлбэл "tootsuud доторх too бүрийн хувьд, хэрэв too тэгш бол, too-г гарга." Энэ бол бүхэл жагсаалтыг шүүх (filter) хамгийн түгээмэл арга бөгөөд та үүнийг үлдсэн сургалтын турш маш олон удаа ашиглана. Бүлэг 6-д JSON-оос уншсан бодит өгөгдлийг шүүх үед яг энэ бичлэг ажиллана.
Comprehension-ы жинхэнэ хүч нь энэ хоёр үйлдлийг НЭГ ЗЭРЭГ хийж чаддагт оршино. Жишээ нь: зөвхөн тэгш тоонуудын квадратыг ав.
python
tootsuud = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
tegsh_kvadrat = [too * too for too in tootsuud if too % 2 == 0]
print(tegsh_kvadrat)Үр дүн:
[4, 16, 36, 64, 100]Энэ нэг мөрийг үг үгээр нь уншъя: "tootsuud доторх too бүрийн хувьд (for too in tootsuud), хэрэв too тэгш бол (if too % 2 == 0), too-ийн квадратыг шинэ list-д нэм (too * too)." Гурван үүрэг — давтах, шүүх, хувиргах — нэг мөрөнд цэвэрхэн багтлаа.
Танил аргаар бичвэл энэ нь долоон мөр болно:
python
tootsuud = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
tegsh_kvadrat = []
for too in tootsuud:
if too % 2 == 0:
tegsh_kvadrat.append(too * too)
print(tegsh_kvadrat)Хоёр код яг ижил үр дүн өгнө, яг ижил хурдтай ажиллана. Ялгаа нь зөвхөн уншигчид юу хэлж байгаад л байна.
Курс 1-ийн хийх ажлын жагсаалтын төслийг санаж байна уу? Тэнд ажлуудын list байсан. Одоо илүү бодит жишээ авъя — үнийн жагсаалтаас 50,000 төгрөгөөс дээш үнэтэй барааны нэрсийг сонгож авъя.
python
baraanuud = ["ном", "компьютер", "харандаа", "утас", "дэвтэр"]
unaguud = [15000, 1500000, 500, 800000, 3000]
unetei = [baraa for baraa, une in zip(baraanuud, unaguud) if une > 50000]
print(unetei)Энд zip гэсэн шинэ зүйл гарч ирлээ — түүнийг Хичээл 2.3-т бүрэн үзнэ, одоохондоо зөвхөн "хоёр жагсаалтыг зэрэгцүүлж явна" гэж ойлгоод өнгөрөөрэй. Гол зүйл нь comprehension-ы бүтэц: for хэсэгт хоёр нэр (baraa, une), if хэсэгт нөхцөл, зүүн талд гаралт.
Үр дүн:
['компьютер', 'утас']Энэ бол Бүлэг 6-д JSON өгөгдлөөс бодит бичлэг шүүхэд ашиглах хэв маягийн шууд өмнөх хувилбар юм. Тэнд baraanuud ба unaguud жагсаалтын оронд бүтэн бүтэцтэй өгөгдөл байх ч, comprehension-ы хэлбэр яг ижилхэн байна.
Одоо би танд заримдаа сурах бичигт бичдэггүй зүйлийг хэлье: comprehension үргэлж илүү сайн байдаггүй.
Comprehension нь энгийн, богино, нэг үйлдлийн хувьд гайхалтай. Гэвч дотор нь хэт олон зүйл хийх гэж оролдвол тэр нь уншихад ойлгомжгүй, толгой эргэм болдог. Жишээ нь ийм код:
python
ur_dun = [x * y for x in range(10) for y in range(10) if x % 2 == 0 if y % 3 == 0 if x + y > 5]Энэ ажиллана. Зөв. Гэхдээ түүнийг уншиж ойлгохын тулд та хэдэн секунд толгойгоо гашилгах хэрэгтэй болно. Ижил кодыг энгийн loop-оор бичвэл хэдэн мөр урт болох ч арав дахин ойлгомжтой болно. Мэргэжлийн код бол хамгийн богино код биш, харин хамгийн ойлгомжтой код юм.
Практик дүрмүүд:
Нэг for, нэмэх нь дээд тал нь нэг if — comprehension ашигла. Ойлгомжтой байна.
Хоёр for үүрлэсэн, эсвэл хэд хэдэн if — энгийн loop бич. Уншигчаа өршөө.
Loop дотор print хийх, файлд бичих, ямар нэг зүйл өөрчлөх шаардлагатай бол — comprehension БИШ, энгийн loop. Comprehension бол ШИНЭ LIST ҮҮСГЭХ хэрэгсэл, үйлдэл гүйцэтгэх хэрэгсэл биш.
Тэр сүүлчийн дүрэм чухал. Ийм код бичих нь техникийн хувьд боломжтой:
python
[print(ner) for ner in nerууd]Гэвч энэ бол буруу хэрэглээ. Та энд None-оор дүүрсэн list үүсгээд шууд хаяж байна — зөвхөн хажуугийн үр дүнг нь ашиглах гэж. Энэ тохиолдолд энгийн loop бичих нь зөв:
python
for ner in nerууd:
print(ner)Хэрэв сонирхвол: өөрийн Курс 1-д бичсэн ямар нэг программаа нээгээд, дотроос нь "хоосон list үүсгээд, loop-оор дүүргэсэн" хэсэг хайж үзээрэй. Тэр хэсгийг comprehension болгож хувиргаж, программ хэвээрээ ажиллаж байгаа эсэхийг шалгаад үзээрэй. Хуучин кодоо шинэ нүдээр харах нь энэ хичээлийг хамгийн сайн бататгах арга.
Мөн хүсвэл: [len(ner) for ner in nerууd] гэж бичээд юу гарахыг таамаглаад, дараа нь ажиллуулж шалгаарай. Таамаг тань зөв гарвал та comprehension-ыг уншиж чаддаг болсныхоо баталгаа авлаа.
1. Хаалтаа мартах
python
kvadratuud = too * too for too in tootsuud File "main.py", line 3
kvadratuud = too * too for too in tootsuud
^^^
SyntaxError: invalid syntaxSyntaxError: invalid syntax гэдэг нь "бичлэг буруу байна" гэсэн ерөнхий алдаа. Энд шалтгаан нь дөрвөлжин хаалт [ ] байхгүй байгаа явдал. Хаалтгүй бол Python үүнийг comprehension гэж танихгүй. Засвар: илэрхийллийг бүхэлд нь [ ] дотор оруулна.
2. if-ийг буруу газар тавих
Эхлэгчид ихэвчлэн if-ийг for-оос ӨМНӨ тавихыг оролддог:
python
tegsh = [too if too % 2 == 0 for too in tootsuud] File "main.py", line 3
tegsh = [too if too % 2 == 0 for too in tootsuud]
^^^
SyntaxError: invalid syntaxШүүх зориулалттай if нь ҮРГЭЛЖ for хэсгийн АРД, comprehension-ы хамгийн төгсгөлд орно. Зөв бичлэг: [too for too in tootsuud if too % 2 == 0]. (Тэмдэглэл: for-оос өмнө if ... else ... бүхэл бүтэн хэлбэр орж болдог — тэр бол өөр зүйл, ternary expression гэж нэрлэгддэг бөгөөд Хичээл 2.5-д үзнэ. Одоохондоо "шүүх if бол төгсгөлд" гэж санаж явахад хангалттай.)
3. Утга буцаадаггүй зүйл бичих
python
ur_dun = [nerууd.append(ner) for ner in nerууd]
print(ur_dun)[None, None, None, None]Энд алдааны мессеж гарахгүй, гэхдээ үр дүн нь утгагүй. append нь юу ч буцаадаггүй (None буцаадаг), тиймээс шинэ list чинь None-оор дүүрнэ. Comprehension-ы зүүн талд ҮРГЭЛЖ УТГА БУЦААДАГ илэрхийлэл байх ёстой. Хэрэв танд утга хэрэггүй, зөвхөн үйлдэл хэрэгтэй бол энгийн loop бич.
4. Хувьсагчийн нэр давхцах
python
too = 100
kvadratuud = [too * too for too in tootsuud]
print(too)100Сонирхолтой нь: comprehension доторх too нь ГАДНА талын too-г өөрчлөхгүй. Comprehension өөрийн гэсэн тусдаа орон зайтай байдаг. Энэ бол сайн зүйл, гэхдээ ижил нэр ашиглах нь уншигчийг төөрөгдүүлдэг тул comprehension дотроо тодорхой, өвөрмөц нэр сонгох нь дээр.
List comprehension бол "хоосон list үүсгэ, loop хий, append хий" гэсэн танил хэв маягийн богино, тод бичлэг. Шинэ хүч биш — шинэ илэрхийлэл.
Үндсэн хэлбэр: [илэрхийлэл for элемент in жагсаалт].
Шүүхийн тулд төгсгөлд if нэмнэ: [илэрхийлэл for элемент in жагсаалт if нөхцөл].
Уншлагын дараалал: for → if → зүүн талын илэрхийлэл.
Зүүн талд үргэлж УТГА буцаадаг илэрхийлэл байх ёстой.
Энгийн тохиолдолд comprehension илүү тод; нарийн, олон давхар тохиолдолд энгийн loop илүү ойлгомжтой. Хамгийн богино код биш, хамгийн ойлгомжтой код зөв.
Дараагийн хичээлд бид яг ижил санааг dictionary дээр хэрэглэнэ. Хэрэв та list-ийг нэг өгүүлбэрээр "захиалж" чадаж байгаа бол dictionary-г ч бас чадна — бичлэг нь бараг ижилхэн, ялгаа нь зөвхөн түлхүүр ба утгыг хамт заах хэсэгт л байна. Мөн товчхон set comprehension-ыг ч танилцуулна.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.