Python тілінде жаңа тізім жасау кезінде тізімді түсіну белгілерін пайдалану оңай.(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 арқылы шартты тармақталу арқылы түсіну белгілерін тізімдеңіз
- Үштік операторлармен біріктіру (егер басқа ұқсас өңдеу)
zip()
,enumerate()
Осылармен комбинация- кірістірілген тізімді қосу белгісі
Әрі қарай, біз үлгі кодымен тізімді түсіну белгілерінің жиынын түсіндіреміз.
- қосу белгісін орнату(
Set comprehensions
) - сөздікті қосу белгісі(
Dict comprehensions
) - генератор түрі(
Generator expressions
)
- Тізімді түсіну белгісінің негізгі түрі
- if арқылы шартты тармақталу арқылы түсіну белгілерін тізімдеңіз
- Үштік операторлармен біріктіру (егер басқа ұқсас өңдеу)
- zip() және enumerate() комбинациясы
- кірістірілген тізімді қосу белгісі
- қосу белгісін орнату(Set comprehensions)
- сөздікті қосу белгісі(Dict comprehensions)
- генератор түрі(Generator expressions)
Тізімді түсіну белгісінің негізгі түрі
Тізімді түсіну белгісі келесідей жазылады.
[Expression for Any Variable Name in Iterable Object]
Ол ерікті айнымалы аты бойынша тізім, кортеж немесе ауқым сияқты қайталанатын нысанның әрбір элементін қабылдайды және оны өрнекпен бағалайды. Элемент ретінде бағалау нәтижесі бар жаңа тізім қайтарылады.
Мысал мәлімдеме үшін баламасымен бірге келтірілген.
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. Постфиксте if сөзін келесідей жазыңыз.
[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]
Дәл осындай процесті filter() арқылы орындауға болады, бірақ оның қарапайымдылығы мен анықтығы үшін тізімді түсіну белгісіне артықшылық беріледі.
Үштік операторлармен біріктіру (егер басқа ұқсас өңдеу)
Жоғарыдағы мысалда критерийлерге сәйкес келетін элементтер ғана өңделеді, ал критерийлерге сәйкес келмейтіндер жаңа тізімнен шығарылады.
Процесті шартқа байланысты ауыстырғыңыз келсе немесе шартты қанағаттандырмайтын элементтерді басқаша өңдегіңіз келсе, басқа сияқты, үштік операторды пайдаланыңыз.
Python тілінде үштік операторды келесідей жазуға болады
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() комбинациясы
for операторында жиі қолданылатын пайдалы функцияларға бірнеше қайталанатын мәндерді біріктіретін zip() және индексімен бірге мәнді қайтаратын enumerate() кіреді.
Әрине, тізімді түсіну белгісімен zip() және enumerate() қолдануға болады. Бұл арнайы синтаксис емес, егер сіз for операторымен сәйкестікті қарастырсаңыз, қиын емес.
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)
Сөздіктерді (dict типті нысандар) түсіну белгісімен де жасауға болады.
{} және өрнек бөлігіндегі кілт пен мәнді кілт ретінде көрсетіңіз: мән.
{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)
Тізім түсінігінің белгілеуіндегі шаршы жақшалар [] дөңгелек жақшалар () ретінде пайдаланылса, кортеж орнына генератор қайтарылады. Бұл генератор өрнектері деп аталады.
Тізімді түсіну белгісінің мысалы.
l = [i**2 for i in range(5)]
print(l)
# [0, 1, 4, 9, 16]
print(type(l))
# <class 'list'>
Генераторлық өрнектің мысалы. Генераторды сол күйінде басып шығарсаңыз() ол оның мазмұнын басып шығармайды, бірақ оны for операторымен іске қоссаңыз, мазмұнды ала аласыз.
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
Генератор өрнектері, сондай-ақ, егер тізімді түсіну белгісімен қатар шартты тармақталуға және кірістіруге мүмкіндік береді.
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)
Мысалы, элементтер саны көп тізім тізімді түсіну белгісі арқылы жасалса, содан кейін for операторымен айналдырылса, тізімді түсіну белгісі пайдаланылса, барлық элементтері бар тізім басында жасалады. Екінші жағынан, егер сіз генератор өрнегін пайдалансаңыз, цикл қайталанған сайын элементтер бір-бірден жасалады, осылайша пайдаланылатын жад көлемі азаяды.
Егер генератор өрнегі функцияның жалғыз аргументі болса, дөңгелек жақшаларды () алып тастауға болады.
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() немесе any() арқылы бағалау кезінде нәтиже жалған немесе ақиқат болғанда анықталады, сондықтан генератор өрнектерін пайдалану тізімді түсіну белгісін пайдаланудан жылдамырақ болуы мүмкін.
Кортежді түсіну белгісі жоқ, бірақ tuple() аргументі ретінде генератор өрнегін пайдалансаңыз, түсіну белгісінде кортежді жасай аласыз.
t = tuple(i**2 for i in range(5))
print(t)
# (0, 1, 4, 9, 16)
print(type(t))
# <class 'tuple'>