នៅក្នុង Python វាគឺសាមញ្ញក្នុងការប្រើ list comprehensions notation នៅពេលបង្កើតបញ្ជីថ្មី។(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
ក្នុងអត្ថបទនេះ យើងនឹងពិភាក្សាគ្នាជាមុនសិនដូចតទៅ
- ប្រភេទមូលដ្ឋាននៃការយល់ឃើញបញ្ជី
- រាយបញ្ជីការយល់ឃើញដោយការបែងចែកតាមលក្ខខណ្ឌដោយ if
- ការរួមបញ្ចូលគ្នាជាមួយប្រតិបត្តិករ ternary (ប្រសិនបើដំណើរការដូចផ្សេងទៀត)
zip()
,enumerate()
ការរួមបញ្ចូលគ្នាជាមួយទាំងនេះ- កំណត់សម្គាល់ការរួមបញ្ចូលបញ្ជីដែលជាប់
បន្ទាប់ យើងនឹងពន្យល់អំពីសំណុំនៃកំណត់ចំណាំការយល់ក្នុងបញ្ជីជាមួយនឹងកូដគំរូ។
- កំណត់ការរួមបញ្ចូល(
Set comprehensions
) - ការរួមបញ្ចូលវចនានុក្រមកំណត់ចំណាំ(
Dict comprehensions
) - ប្រភេទម៉ាស៊ីនភ្លើង(
Generator expressions
)
- ប្រភេទមូលដ្ឋាននៃការយល់ឃើញបញ្ជី
- រាយបញ្ជីការយល់ឃើញដោយការបែងចែកតាមលក្ខខណ្ឌដោយ if
- ការរួមបញ្ចូលគ្នាជាមួយប្រតិបត្តិករ ternary (ប្រសិនបើដំណើរការដូចផ្សេងទៀត)
- ការរួមបញ្ចូលគ្នាជាមួយ zip() និង enumerate()
- កំណត់សម្គាល់ការរួមបញ្ចូលបញ្ជីដែលជាប់
- កំណត់ការរួមបញ្ចូល(Set comprehensions)
- ការរួមបញ្ចូលវចនានុក្រមកំណត់ចំណាំ(Dict comprehensions)
- ប្រភេទម៉ាស៊ីនភ្លើង(Generator expressions)
ប្រភេទមូលដ្ឋាននៃការយល់ឃើញបញ្ជី
កំណត់ចំណាំក្នុងបញ្ជីត្រូវបានសរសេរដូចខាងក្រោម។
[Expression for Any Variable Name in Iterable Object]
វាយកធាតុនីមួយៗនៃវត្ថុដែលអាចបំលែងបាន ដូចជាបញ្ជីមួយ tuple ឬជួរដោយឈ្មោះអថេរបំពាន ហើយវាយតម្លៃវាដោយប្រើកន្សោម។ បញ្ជីថ្មីដែលមានលទ្ធផលវាយតម្លៃជាធាតុមួយត្រូវបានបញ្ជូនមកវិញ។
ឧទាហរណ៍មួយត្រូវបានផ្តល់ឱ្យរួមជាមួយនឹងសមមូលសម្រាប់សេចក្តីថ្លែងការណ៍។
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]
ដំណើរការដូចគ្នាអាចត្រូវបានធ្វើជាមួយ map() ប៉ុន្តែការយល់ឃើញបញ្ជីត្រូវបានពេញចិត្តសម្រាប់ភាពសាមញ្ញ និងភាពច្បាស់លាស់របស់វា។
រាយបញ្ជីការយល់ឃើញដោយការបែងចែកតាមលក្ខខណ្ឌដោយ if
ការបែងចែកតាមលក្ខខណ្ឌជាមួយប្រសិនបើអាចធ្វើទៅបានផងដែរ។ សរសេរ if នៅក្នុង postfix ដូចខាងក្រោម។
[Expression for Any Variable Name in Iterable Object if Conditional Expression]
មានតែធាតុនៃវត្ថុដែលអាចប្រើវាបានដែលកន្សោមតាមលក្ខខណ្ឌគឺពិតត្រូវបានវាយតម្លៃដោយកន្សោម ហើយបញ្ជីថ្មីដែលធាតុរបស់វាជាលទ្ធផលត្រូវបានត្រឡប់មកវិញ។
អ្នកអាចប្រើឈ្មោះអថេរណាមួយនៅក្នុងកន្សោមតាមលក្ខខណ្ឌ។
ឧទាហរណ៍មួយត្រូវបានផ្តល់ឱ្យរួមជាមួយនឹងសមមូលសម្រាប់សេចក្តីថ្លែងការណ៍។
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]
ដំណើរការដូចគ្នាអាចត្រូវបានធ្វើដោយតម្រង () ប៉ុន្តែការយល់ឃើញបញ្ជីត្រូវបានពេញចិត្តសម្រាប់ភាពសាមញ្ញ និងភាពច្បាស់លាស់របស់វា។
ការរួមបញ្ចូលគ្នាជាមួយប្រតិបត្តិករ ternary (ប្រសិនបើដំណើរការដូចផ្សេងទៀត)
ក្នុងឧទាហរណ៍ខាងលើ មានតែធាតុដែលបំពេញតាមលក្ខណៈវិនិច្ឆ័យប៉ុណ្ណោះដែលត្រូវបានដំណើរការ ហើយធាតុដែលមិនបំពេញតាមលក្ខណៈវិនិច្ឆ័យត្រូវបានដកចេញពីបញ្ជីថ្មី។
ប្រសិនបើអ្នកចង់ប្តូរដំណើរការអាស្រ័យលើលក្ខខណ្ឌ ឬប្រសិនបើអ្នកចង់ដំណើរការធាតុដែលមិនបំពេញលក្ខខណ្ឌខុសគ្នាដូចក្នុងវិធីផ្សេងទៀត សូមប្រើប្រតិបត្តិករ ternary ។
នៅក្នុង Python ប្រតិបត្តិករ ternary អាចត្រូវបានសរសេរដូចខាងក្រោម
Value When True if Conditional Expression else Value When False
វាត្រូវបានប្រើនៅក្នុងផ្នែកកន្សោមនៃការយល់ដឹងបញ្ជីដូចដែលបានបង្ហាញខាងក្រោម។
[Value When True if Conditional Expression else Value When False for Any Variable Name in Iterable Object]
ឧទាហរណ៍មួយត្រូវបានផ្តល់ឱ្យរួមជាមួយនឹងសមមូលសម្រាប់សេចក្តីថ្លែងការណ៍។
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']
វាក៏អាចធ្វើទៅបានផងដែរក្នុងការសរសេរកន្សោមដោយប្រើឈ្មោះអថេរបំពានសម្រាប់តម្លៃពិតនិងមិនពិត។
ប្រសិនបើលក្ខខណ្ឌត្រូវបានពេញចិត្ត ដំណើរការមួយចំនួនត្រូវបានធ្វើរួច បើមិនដូច្នេះទេ តម្លៃនៃវត្ថុដែលអាចប្រើឡើងវិញបានគឺនៅដដែល។
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]
ការរួមបញ្ចូលគ្នាជាមួយ zip() និង enumerate()
មុខងារមានប្រយោជន៍ដែលជារឿយៗត្រូវបានប្រើប្រាស់ក្នុងសេចក្តីថ្លែងការណ៍រួមមាន zip() ដែលរួមបញ្ចូលគ្នានូវ iteables ច្រើន និង enumerate() ដែលផ្តល់លទ្ធផលតម្លៃរួមជាមួយនឹងលិបិក្រមរបស់វា។
ជាការពិតណាស់ វាអាចប្រើ zip() និង enumerate() ជាមួយនឹង list comprehension notation។ វាមិនមែនជាវាក្យសម្ព័ន្ធពិសេសទេ ហើយវាមិនពិបាកទេ ប្រសិនបើអ្នកពិចារណាការឆ្លើយឆ្លងជាមួយសេចក្តីថ្លែងការណ៍។
ឧទាហរណ៍នៃ 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')]
ឧទាហរណ៍នៃ 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')]
គំនិតគឺដូចគ្នានឹងពីមុននៅពេលប្រើ 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')]
ធាតុនីមួយៗក៏អាចត្រូវបានប្រើដើម្បីគណនាធាតុថ្មីផងដែរ។
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]
កំណត់សម្គាល់ការរួមបញ្ចូលបញ្ជីដែលជាប់
ដូចជាការដាក់សំបុកសម្រាប់រង្វិលជុំ បញ្ជីកំណត់ចំណាំដែលអាចយល់បានក៏អាចត្រូវបានដាក់នៅក្នុងសំណាញ់បានដែរ។
[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 ... ]
ដើម្បីភាពងាយស្រួល ការបំបែកបន្ទាត់ និងការចូលបន្ទាត់ត្រូវបានបន្ថែម ប៉ុន្តែមិនត្រូវបានទាមទារសម្រាប់វេយ្យាករណ៍ទេ។ ពួកគេអាចត្រូវបានបន្តនៅលើបន្ទាត់តែមួយ។
ឧទាហរណ៍មួយត្រូវបានផ្តល់ឱ្យរួមជាមួយនឹងសមមូលសម្រាប់សេចក្តីថ្លែងការណ៍។
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]
វាក៏អាចប្រើអថេរច្រើនផងដែរ។
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)]
អ្នកក៏អាចធ្វើសាខាតាមលក្ខខណ្ឌផងដែរ។
cells = [(row, col) for row in range(3)
for col in range(2) if col == row]
print(cells)
# [(0, 0), (1, 1)]
វាក៏អាចធ្វើទៅបានតាមលក្ខខណ្ឌសម្រាប់វត្ថុដែលអាចបំប្លែងបាននីមួយៗ។
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)]
កំណត់ការរួមបញ្ចូល(Set comprehensions)
ការផ្លាស់ប្តូរតង្កៀបការ៉េ [] នៅក្នុងបញ្ជីកំណត់ចំណាំទៅតង្កៀបអង្កាញ់ {} បង្កើតសំណុំ (សំណុំប្រភេទវត្ថុ) ។
{Expression for Any Variable Name in Iterable Object}
s = {i**2 for i in range(5)}
print(s)
# {0, 1, 4, 9, 16}
ការរួមបញ្ចូលវចនានុក្រមកំណត់ចំណាំ(Dict comprehensions)
វចនានុក្រម (វត្ថុប្រភេទពាក្យបញ្ជា) ក៏អាចត្រូវបានបង្កើតជាមួយនឹងសញ្ញាណដែលអាចយល់បាន។
{} ហើយបញ្ជាក់គន្លឹះ និងតម្លៃនៅក្នុងផ្នែកកន្សោមជា key៖ តម្លៃ។
{Key: Value for Any Variable Name in Iterable Object}
កន្សោមណាមួយអាចត្រូវបានបញ្ជាក់សម្រាប់គន្លឹះ និងតម្លៃ។
l = ['Alice', 'Bob', 'Charlie']
d = {s: len(s) for s in l}
print(d)
# {'Alice': 5, 'Bob': 3, 'Charlie': 7}
ដើម្បីបង្កើតវចនានុក្រមថ្មីពីបញ្ជីគ្រាប់ចុច និងតម្លៃ សូមប្រើមុខងារ 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}
ប្រភេទម៉ាស៊ីនភ្លើង(Generator expressions)
ប្រសិនបើតង្កៀបការ៉េ [] នៅក្នុងបញ្ជីកំណត់ចំណាំដែលយល់ត្រូវត្រូវបានប្រើជាតង្កៀបមូល () ម៉ាស៊ីនភ្លើងត្រូវបានត្រឡប់ជំនួសឱ្យ tuple ។ នេះហៅថា កន្សោមម៉ាស៊ីនភ្លើង។
ឧទាហរណ៍នៃការយល់ឃើញបញ្ជី។
l = [i**2 for i in range(5)]
print(l)
# [0, 1, 4, 9, 16]
print(type(l))
# <class 'list'>
ឧទាហរណ៍នៃកន្សោមម៉ាស៊ីនភ្លើង។ ប្រសិនបើអ្នកបោះពុម្ព () ម៉ាស៊ីនភ្លើងដូចដែលវាគឺ វានឹងមិនអាចបោះពុម្ពមាតិការបស់វាចេញទេ ប៉ុន្តែប្រសិនបើអ្នកដំណើរការវាដោយប្រើសេចក្តីថ្លែងការណ៍ អ្នកអាចទទួលបានមាតិកា។
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
កន្សោមម៉ាស៊ីនភ្លើងក៏អនុញ្ញាតឱ្យមានការបែងចែកតាមលក្ខខណ្ឌ និងការដាក់សំបុកដោយប្រើ if ព្រមទាំងរាយបញ្ជីកំណត់ចំណាំការយល់ដឹង។
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)
ឧទាហរណ៍ ប្រសិនបើបញ្ជីដែលមានធាតុមួយចំនួនធំត្រូវបានបង្កើតដោយប្រើកំណត់ចំណាំក្នុងបញ្ជី ហើយបន្ទាប់មកភ្ជាប់ជាមួយសេចក្តីថ្លែងការណ៍មួយ នោះបញ្ជីដែលមានធាតុទាំងអស់នឹងត្រូវបានបង្កើតនៅដើម ប្រសិនបើការកំណត់ការយល់បញ្ជីត្រូវបានប្រើប្រាស់។ ម្យ៉ាងវិញទៀត ប្រសិនបើអ្នកប្រើកន្សោមម៉ាស៊ីនភ្លើង រាល់ពេលដែលរង្វិលជុំត្រូវបានធ្វើម្តងទៀត ធាតុត្រូវបានបង្កើតម្តងមួយៗ ដូច្នេះកាត់បន្ថយចំនួនអង្គចងចាំដែលបានប្រើ។
ប្រសិនបើកន្សោមម៉ាស៊ីនភ្លើងគឺជាអាគុយម៉ង់តែមួយគត់នៃមុខងារនោះ តង្កៀបមូល () អាចត្រូវបានលុបចោល។
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
ចំពោះល្បឿនដំណើរការ ការកំណត់ចំណាំក្នុងបញ្ជីតែងតែលឿនជាងការសម្គាល់ម៉ាស៊ីនភ្លើង នៅពេលដែលធាតុទាំងអស់ត្រូវបានដំណើរការ។
ទោះយ៉ាងណាក៏ដោយ នៅពេលវិនិច្ឆ័យជាមួយ all() ឬណាមួយ () ឧទាហរណ៍ លទ្ធផលត្រូវបានកំណត់នៅពេលដែលមិនពិត ឬពិតមានវត្តមាន ដូច្នេះការប្រើកន្សោមម៉ាស៊ីនភ្លើងអាចលឿនជាងការប្រើសញ្ញាសម្គាល់ការយល់បញ្ជី។
មិនមានកំណត់ចំណាំការយល់ច្បាស់ tuple ទេ ប៉ុន្តែប្រសិនបើអ្នកប្រើកន្សោមម៉ាស៊ីនភ្លើងជាអាគុយម៉ង់នៃ tuple() អ្នកអាចបង្កើត tuple នៅក្នុងសញ្ញាណនៃការយល់ដឹង។
t = tuple(i**2 for i in range(5))
print(t)
# (0, 1, 4, 9, 16)
print(type(t))
# <class 'tuple'>