Python: деректен өз есебіңізге дейін 15-сабақ (барлығы 56)
Жиындар: `&`, `-`, `|` және екінші выгрузкада жоқ нәрсе
Python курсының он бесінші сабағы. Тізімдегі бес атаудың әртүрлісі — төртеу: жиын қайталауды үнсіз жеп қояды. Оның есесіне екі деректер экспортына қойылған үш сұрақ үш таңбамен шешіледі: `&` — екеуінде де не бар, `-` — не қалмаған, `|` — бәрі бірге. Плюс `{}` — бос жиын емес, бос сөздік.
Не үшін керек
Тізімдер мен сөздіктер «нешеу» және «осы кілт бойынша не бар» деген сұрақтарға жауап береді. Деректермен жұмыста бәрінен жиі қойылатын үшінші сұрақ бар: бар ма, жоқ па.
Екі деректер экспорты келді — қаңтар мен ақпан. Екеуінде де не болды? Екіншісінде не қалмады? Не жаңа пайда болды? Тізіммен мұны кірістірілген циклмен санайды, әрі онда қателесу оңай.
Жиын — қайталаусыз және ретсіз жинақ. «Бар ма, жоқ па» үшін керегінің дәл өзі, әрі екі деректер экспортына қойылған үш сұрақты ол үш таңбамен шешеді.
Бірден тұтас
jiyn.py файлы. Іске қосу: ортадан python jiyn.py.
Міндеттісі — алғашқы екі блок: тізімді жиынға айналдыру және үш амал. Үшінші мен төртіншісі орнында тексеруді және екі тұзақты көрсетеді.
"""15-сабақ: жиын — «бар ма, жоқ па» туралы, «нешеу және қай ретпен» туралы емес.
Әр айдағы екі тауар деректер экспорты. Оларға қойылатын сұрақ бірдей: екеуінде де не
бар, екіншісінде не қалмаған, не жаңа пайда болған. Тізіммен мұны циклмен
санайды, жиынмен — бір таңбамен.
"""
january = ["нан", "сүт", "май", "тұз", "нан"]
february = ["нан", "сүт", "қант", "жұмыртқа"]
print("== жиынға айналдырғанда не жоғалады")
a = set(january)
b = set(february)
print("қаңтар тізімінде:", len(january), "| әртүрлі атау:", len(a))
print("жиынды сұрыпталған күйде басады:", sorted(a))
print()
print("== үш сұрақ — үш таңба")
print("екеуінде де бар (a & b): ", sorted(a & b))
print("екіншісінде жоқ (a - b): ", sorted(a - b))
print("пайда болды (b - a): ", sorted(b - a))
print("бәрі бірге (a | b): ", sorted(a | b))
print("тек біреуінде (a ^ b): ", sorted(a ^ b))
print()
print("== бар ма, жоқ па, әрі ішіне кіре ме")
print("«тұз» қаңтарда:", "тұз" in a, "| ақпанда:", "тұз" in b)
print("ақпан қаңтардың ішінде:", b <= a, "| қиылысады:", not a.isdisjoint(b))
print("екі айда барлығы неше түрлі:", len(a | b))
print()
print("== екі тұзақ")
print("{} типі —", type({}).__name__, "| set() типі —", type(set()).__name__)
try:
{["нан", "сүт"]}
except TypeError as error:
print("тізімді ішіне салуға болмайды:", error)
Шығатыны:
== жиынға айналдырғанда не жоғалады
қаңтар тізімінде: 5 | әртүрлі атау: 4
жиынды сұрыпталған күйде басады: ['май', 'нан', 'сүт', 'тұз']
== үш сұрақ — үш таңба
екеуінде де бар (a & b): ['нан', 'сүт']
екіншісінде жоқ (a - b): ['май', 'тұз']
пайда болды (b - a): ['жұмыртқа', 'қант']
бәрі бірге (a | b): ['жұмыртқа', 'май', 'нан', 'сүт', 'тұз', 'қант']
тек біреуінде (a ^ b): ['жұмыртқа', 'май', 'тұз', 'қант']
== бар ма, жоқ па, әрі ішіне кіре ме
«тұз» қаңтарда: True | ақпанда: False
ақпан қаңтардың ішінде: False | қиылысады: True
екі айда барлығы неше түрлі: 6
== екі тұзақ
{} типі — dict | set() типі — set
тізімді ішіне салуға болмайды: cannot use 'list' as a set element (unhashable type: 'list')
Талдау
Қайталаулар үнсіз жоғалады
қаңтар тізімінде: 5 | әртүрлі атау: 4
set(january) екінші «нанды» ештеңе демей лақтырып тастайды. Жиынның басты қасиеті осы: элемент не бар, не жоқ, ал ол неше рет кездескені — оған қойылатын сұрақ емес.
Осыдан ең жиі кездесетін адал қолданысы шығады: деректе неше әртүрлі мән бар екенін санау. len(set(...)) мен len(...) — бір жол, әрі деректер экспортында дубликат бар-жоғы бірден көрінеді.
Осыдан қате де шығады: қайталау дерек болып тұрған жерде жиынды алуға болмайды. Айына үш рет нан сатып алу — бұл үш сатып алу, біреу емес; ол үшін жиын емес, тізім не санауыш керек.
Елестетіп көріңіз. Шақырылғандар тізімі. Онда кімнің шақырылғаны маңызды, оны неше рет жазғаны емес. Ал бұл сатып алу тізімі болса, екі нан — бұл екі нан.
Реті жоқ, сондықтан sorted арқылы басады
print("жиынды сұрыпталған күйде басады:", sorted(a))
Жиында рет жоқ — қосқан реті де, басқасы да. Оны тікелей басып шығарыңыз, әрі рет басқа машинада немесе басқа іске қосуда өзгеше болуы мүмкін: ол элементтердің іште қалай орналасқанына тәуелді.
Сондықтан ереже қарапайым: жиынды sorted арқылы көрсетеді. Сонда шығу бәрінде бірдей болады, әрі оны көзбен салыстыруға келеді. Бағдарламаның ішінде рет керек емес — онда жиыннан сұрайды, оны оқымайды.
Үш сұрақ — үш таңба
екеуінде де бар (a & b): ['нан', 'сүт']
екіншісінде жоқ (a - b): ['май', 'тұз']
пайда болды (b - a): ['жұмыртқа', 'қант']
& — қиылысу: екеуінде де не бар. - — айырма: біріншісінде бар, екіншісінде жоқ. | — бірігу: бәрі бірге, әрқайсысы бір реттен. ^ — симметриялы айырма: тек екеуінің біреуінде ғана бар нәрсе.
- таңбасында рет маңызды: a - b пен b - a әртүрлі сұраққа жауап береді — «не қалмады» және «не пайда болды». Бұл — бастапқыда ең жиі шатасатын жер, әрі ол дауыстап қойылған сұрақпен емделеді: қай жиыннан азайтып тұрмыз.
Барлық таңбаның сөзбен жазылған сыңары бар: a.intersection(b), a.difference(b), a.union(b), a.symmetric_difference(b). Таңба қысқа, сөз бөтен кодта түсініктірек — сол жерде қайсысы жақсы оқылса, соны алады.
«Бар ма, жоқ па» — жиындар сол үшін ойлап табылған
"тұз" in a
in тексеруі тізіммен де, жиынмен де жұмыс істейді, бірақ әртүрлі. Тізімде Python элементтерді тапқанша аралайды: тізім неғұрлым ұзын болса, соғұрлым ұзақ. Жиында ол элемент қай жерде жатуға тиіс екенін бірден есептейді де, тек сол жерге қарайды — ұзындықтың мәні жоқ.
Он жолда айырма байқалмайды. Циклмен тексерілетін жүз мың жолдық деректер экспортында бұл — «бір секунд» пен «жарты сағаттың» айырмасы, әрі жиынды кейде тек тексеру үшін бастаудың жалғыз себебі де сол.
Қасында тұтас жинақ туралы сұрақтар тұр: b <= a — b-ның барлық элементі a-да бар ма; a.isdisjoint(b) — олар мүлде қиылыспай ма.
Екі тұзақ
{} типі — dict | set() типі — set
Жүйелі жақшаны сөздік алып қойған: {} — бұл бос сөздік, бос жиын емес. Бос жиын — тек set(). Қате бірден көрінбейді: seen = {} бірінші seen.add(...) жолына дейін жұмыс істейді де, сол жерде сөздікте add жоқ дейді.
тізімді ішіне салуға болмайды: cannot use 'list' as a set element (unhashable type: 'list')
Жиынға өзгертуге келмейтін нәрсені ғана салуға болады: сандар, жолдар, кортеждер. Тізім өзгермелі — демек, оны ішіне салып, орны бойынша қойылған элементті өзгертуге болар еді, сонда жиын өзін-өзі таппай қалар еді.
Себебі сөздіктің кілті тізім болмайтын себеппен бірдей: екі жерде де элемент хеш бойынша орналастырылады. Өзгермейтін жинақ керек болса — frozenset бар, әрі оны басқа жиынның ішіне салуға болады.
Сабақ картасы
Өз сөзіңізбен айтыңыз
Қарамай, дауыстап немесе қағазға жауап беріңіз. Жауаптары — сабақтың соңында.
- Жиын қайталаулармен не істейді, әрі бұл қашан зиянды?
- Екі деректер экспортында
a - bb - a-дан немен өзгеше? - Жиынды неге
sortedарқылы басып шығарады?
Жаттығу
Тапсырмаға дейінгі үш қысқа қадам: болжау, толықтыру, жөндеу. Жауаптары — сабақтың соңында, бірақ алдымен өзіңіз жауап беріңіз.
1. Болжаңыз. Бұл жол не басып шығарады?
print(len([1, 2, 2, 3]), len({1, 2, 2, 3}))
2. Бос орынды толтырыңыз. ... орнына екінші деректер экспортында жоқ атауларды қалдыратын нәрсені қойыңыз.
a = {"нан", "сүт", "тұз"}
b = {"нан", "сүт", "қант"}
print(sorted(...))
3. Жөндеңіз. Бағдарлама екінші жолда құлайды. Қатені оқып, шынымен керегін жасаңыз.
seen = {}
seen.add("нан")
print(sorted(seen))
Тапсырма
Міндетті. Берілгені:
january = ["нан", "сүт", "май", "тұз", "нан", "жұмыртқа"]
february = ["нан", "сүт", "қант", "жұмыртқа", "жұмыртқа"]
Әр ай бойынша неше позиция болғанын және олардың ішінде нешеуі әртүрлі екенін басып шығарыңыз. Содан кейін үш жауап: екінші айда не қалмағанын, не жаңа пайда болғанын, екеуінде де не қалғанын. Соңында — екі айда барлығы неше әртүрлі атау бар екенін. Барлық жинақты sorted арқылы басыңыз.
Күтілетін шығу:
қаңтар: позиция 6 | әртүрлі 5
ақпан: позиция 5 | әртүрлі 4
екіншісінде жоқ: ['май', 'тұз']
екіншісінде пайда болды: ['қант']
екеуінде де қалды: ['жұмыртқа', 'нан', 'сүт']
екі айда барлығы әртүрлі: 6
Дайын болғаны: шығу жол-жолмен сәйкес келеді; бірде-бір кірістірілген цикл жоқ — үш жауап та таңбамен алынған; әр жиын тікелей емес, sorted арқылы басылған.
Өз деректеріңізде. Өзіңіздің екі тізіміңізді алыңыз — екі чектегі тауарлар, екі чаттағы қатысушылар, екі қалтадағы файлдар. Сол үш сұраққа жауап беріңіз де, олардың қайсысы өміріңізде жиірек керек болатынын дауыстап айтыңыз.
Қалауыңызша.
- Жиынды
sorted-сіз бірнеше рет қатарынан басып шығарып, ретіне қараңыз. - Бірінші айдан
frozensetжинап, оны басқа жиынның ішіне салыңыз. - Әр атаудың неше рет кездескенін санаңыз да, мұнда жиын неге жарамайтынын түсіндіріңіз.
Жобада бұл қайда тұрады
Шолу жоғалуларды байқай бастайды. Бұрын ол келгенін санайтын; енді өткенімен салыстырғанда жаңа деректер экспортында не жоқ екенін айта алады — ал бұл әлемнің емес, дереккөздің сынғанының алғашқы белгісі.
Қарыздар. Жиын «бар ма, жоқ па» дегенге жауап береді, «неше рет» дегенге емес — ол үшін санауыш керек, әрі ол collections модулі туралы сабақта пайда болады. Ретті де сақтамайды, сондықтан «алғашқы бес жаңасын» одан сұрыптаусыз алу мүмкін емес.
Жауаптар
Жауаптарды көрсету
Сұрақтарға
- Оларды үнсіз лақтырып тастайды: элемент не бар, не жоқ. Қайталау дерек болып тұрған жерде бұл зиянды: үш рет алынған нан біреу болып қалады да, чектің сомасы дұрыс шықпайды.
a - b— екінші деректер экспортында не қалмағаны,b - a— онда не пайда болғаны. Сұрақтар әртүрлі, әрі қайсысына жауап бергеніңізді азайту реті шешеді.- Өйткені жиынның өз реті жоқ: тікелей шығу басқа машинада не басқа іске қосуда өзгеше болуы мүмкін.
sortedшығуды бәріне бірдей етеді.
Жаттығуға
4 3. Тізімде төрт элемент, жиында — үшеу: екінші екілік онда жоқ, әрі бұл туралы ешкім хабарламады.
4 3
a - b. Осы реттегі айырма бірінші жинақта бар, екіншісінде жоқ нәрсені қалдырады.
a = {"нан", "сүт", "тұз"}
b = {"нан", "сүт", "қант"}
print(sorted(a - b))
['тұз']
{}— бос жиын емес, бос сөздік, сондықтан ондаaddтабылмады:AttributeError: 'dict' object has no attribute 'add'. Бос жиындыset()арқылы жасайды.
seen = set()
seen.add("нан")
print(sorted(seen))
['нан']
Пікірлер (0)
Пікір қалдыру үшін кіріңіз →
Әзірге пікір жоқ. Бірінші болыңыз.