Python: деректен өз есебіңізге дейін 6-сабақ (барлығы 56)
Сөздік: рет үмітінің орнына байланыс
Python курсының алтыншы сабағы. Атау бойынша бағалар: қатенің орнына `get`, аралаудың орнына `in`, дайын кесте ретінде `items()`. Өлшенді: жоқ кілтке жүгіну — бос емес, `KeyError`; Counter себетті бір жолда санайды, ал defaultdict кәдімгі сөздік құлайтын жерде нөлді өзі қояды.
Не үшін керек
Өткен сабақта атаулар бір тізімде, бағалар екіншісінде жатты, ал олардың арасындағы байланыс ар-ұятқа сүйенді: бірінші тізімнің үшінші элементі екінші тізімнің үшінші элементіне қатысты. Бір тізім жылжыса болды — сүт майдың бағасына шығады.
Сөздік байланысты айқын етеді: әр мәннің оны табатын кілті бар. Ал бағалар туралы деректегі жыл — бұл да кілт.
Бірден тұтас
sozdik.py файлы. Іске қосу: ортадан python sozdik.py.
Бағдарлама ұзын — алпыс жол. Міндеттісі: сөздіктің өзі, get, in және items(). Соңындағы Counter мен defaultdict — соның үстінен: оларды бет-жүзінен танып қойса жеткілікті, тапсырмада керегі жоқ.
"""6-сабақ: сөздік — атау мен мәннің арасындағы байланыс.
Өткен сабақта атаулар мен бағалар екі тізімде жатты, әрі олардың ретін есте
ұстауға тура келді. Сөздік бұл үмітті байланысқа ауыстырады.
"""
from collections import Counter, defaultdict
# Сөздік: кілт — соның бойынша іздейтін нәрсе, мән — табылатын нәрсе.
prices = {"нан": 280, "сүт": 620, "май": 1890, "тұз": 90}
print("== сөздік түгел әрі кілт бойынша")
print("бүкіл сөздік:", prices)
print("нешеу жазба:", len(prices))
print("сүттің бағасы:", prices["сүт"])
print()
print("== кілт жоқ — бұл бос емес, қате")
try:
print(prices["қант"])
except KeyError as err:
print("prices[\"қант\"] →", type(err).__name__, "—", err)
print("get() қауіпсіз:", prices.get("қант"))
print("әдепкі мәнмен get():", prices.get("қант", 0), "теңге")
print("тұз бар ма:", "тұз" in prices)
print("қант бар ма:", "қант" in prices)
print()
print("== сөздікті өзгертеді")
prices["қант"] = 450
print("қант қостық:", prices)
prices["нан"] = 310
print("нан қымбаттады:", prices)
removed = prices.pop("тұз")
print("тұзды алып тастадық,", removed, "→", prices)
print()
print("== ішінде не бар: кілттер, мәндер, жұптар")
print("кілттер: ", list(prices.keys()))
print("мәндер: ", list(prices.values()))
print("жұптар: ", list(prices.items()))
print("барлық баға сомасы:", sum(prices.values()))
print("ең қымбаты:", max(prices, key=prices.get))
print()
print("== жыл мен мәннің сөздігі — біз алып та қойғанымыз")
cpi = {2010: 100.0, 2015: 137.8, 2020: 202.0, 2025: 348.1}
print("жылдар бойынша баға индексі:", cpi)
print("2010-нан бері неше есе:", round(cpi[2025] / cpi[2010], 2))
print("жылдар бойынша сұрыпталды:", sorted(cpi.items()))
print()
print("== нешеуден бар екенін санау: Counter")
basket = ["нан", "сүт", "нан", "май", "нан", "сүт"]
counts = Counter(basket)
print("себетте не бар:", counts)
print("нан:", counts["нан"], "| қант:", counts["қант"], "← Counter-де қате жоқ")
print("ең жиі екеуі:", counts.most_common(2))
print()
print("== defaultdict: мәні өзі пайда болатын сөздік")
plain = {}
try:
plain["нан"] += 1
except KeyError as err:
print("кәдімгі сөздік →", type(err).__name__, "—", err)
counted = defaultdict(int)
counted["нан"] += 1
counted["нан"] += 1
print("defaultdict істеді:", dict(counted))
Шығатыны:
== сөздік түгел әрі кілт бойынша
бүкіл сөздік: {'нан': 280, 'сүт': 620, 'май': 1890, 'тұз': 90}
нешеу жазба: 4
сүттің бағасы: 620
== кілт жоқ — бұл бос емес, қате
prices["қант"] → KeyError — 'қант'
get() қауіпсіз: None
әдепкі мәнмен get(): 0 теңге
тұз бар ма: True
қант бар ма: False
== сөздікті өзгертеді
қант қостық: {'нан': 280, 'сүт': 620, 'май': 1890, 'тұз': 90, 'қант': 450}
нан қымбаттады: {'нан': 310, 'сүт': 620, 'май': 1890, 'тұз': 90, 'қант': 450}
тұзды алып тастадық, 90 → {'нан': 310, 'сүт': 620, 'май': 1890, 'қант': 450}
== ішінде не бар: кілттер, мәндер, жұптар
кілттер: ['нан', 'сүт', 'май', 'қант']
мәндер: [310, 620, 1890, 450]
жұптар: [('нан', 310), ('сүт', 620), ('май', 1890), ('қант', 450)]
барлық баға сомасы: 3270
ең қымбаты: май
== жыл мен мәннің сөздігі — біз алып та қойғанымыз
жылдар бойынша баға индексі: {2010: 100.0, 2015: 137.8, 2020: 202.0, 2025: 348.1}
2010-нан бері неше есе: 3.48
жылдар бойынша сұрыпталды: [(2010, 100.0), (2015, 137.8), (2020, 202.0), (2025, 348.1)]
== нешеуден бар екенін санау: Counter
себетте не бар: Counter({'нан': 3, 'сүт': 2, 'май': 1})
нан: 3 | қант: 0 ← Counter-де қате жоқ
ең жиі екеуі: [('нан', 3), ('сүт', 2)]
== defaultdict: мәні өзі пайда болатын сөздік
кәдімгі сөздік → KeyError — 'нан'
defaultdict істеді: {'нан': 2}
Талдау
Кілт пен мән
prices = {"нан": 280, "сүт": 620, "май": 1890, "тұз": 90}
Фигуралық жақшалар, жұптар қос нүкте арқылы. Сол жақта кілт — соның бойынша іздейді; оң жақта мән — табылатыны. prices["сүт"] қалғанын араламай, бірден 620 береді.
Кілт жол да, сан да, кортеж де бола алады — сөздік танитын тұрақты «таңбасы» барлардың бәрі. Тізім кілт бола алмайды: ол өзгереді, таңбасы да онымен бірге өзгереді. Бұл қасиеттің дәл атауы — хештелетіндік, ол «өзгермейтінге» тең емес: ішінде тізімі бар кортеж өзі өзгермейді, бірақ кілт бола алмайды — ішіндегісі өзгереді.
Кілт жоқ — бұл қате
prices["қант"] → KeyError — 'қант'
Python үнсіз бос мән қайтармайды: кілт жоқ болса — ерекше жағдай. Бұл дұрыс, өйткені «дерек жоқ» пен «нөл» — екі басқа нәрсе, оларды есептеуде шатастыру қауіпті.
Кілттің болмауы қалыпты жағдай болса, get арқылы сұрайды:
get() қауіпсіз: None
әдепкі мәнмен get(): 0 теңге
get(кілт) None қайтарады, get(кілт, 0) — нөл. Ал кілттің бар-жоғын білу керек болса — in операторы: "тұз" in prices True береді.
Елестетіп көріңіз. Телефон кітапшасы. «Асхаттың телефоны» деп сұрап, «ондай жоқ» деген қатені алу — бос нөмір алып, ешқайда қоңырау шалғаннан шыншыл.
Сөздікті өзгерту
Кілт бойынша меншіктеу кілт болмаса жазба қосады, болса мәнді ауыстырады. pop өшіріп, өшірілгенді қайтарады.
Шығыстағы ретке назар аударыңыз: ол сақталады — қосылған қалпында. Бұл Python 3.7-ден бері кепілдендірілген және ыңғайлы, бірақ ретке мағына ретінде сүйенбеген жөн: сөздікті орны бойынша емес, кілті бойынша іздейді.
Кілттер, мәндер және жұптар
кілттер: ['нан', 'сүт', 'май', 'қант']
мәндер: [310, 620, 1890, 450]
жұптар: [('нан', 310), ('сүт', 620), ('май', 1890), ('қант', 450)]
.items() жұптар береді — өткен сабақтағы сол кортеждер. Жұптар тізімі — бұл қазірдің өзінде кесте, сөздік дерекке дәл осылай айналады.
sum(prices.values()) барлық бағаның сомасын санайды. max(prices, key=prices.get) мәні ең үлкен кілтті қайтарады — яғни бағаның өзін емес, ең қымбат тауардың атауын.
Жыл — кілт ретінде
cpi = {2010: 100.0, 2015: 137.8, 2020: 202.0, 2025: 348.1}
Бұл — бірінші сабақтағы бағдарламамыз Дүниежүзілік банктен алғаны: жылдар бойынша баға индексі. Енді оның не болғаны түсінікті — кілті жыл, мәні индекс болатын сөздік.
cpi[2025] / cpi[2010] сол 3.48-ді береді. Ал sorted(cpi.items()) жұптарды жылдар бойынша тізеді — графикке дайын дерек.
Counter: нешеуден бар екенін санау
себетте не бар: Counter({'нан': 3, 'сүт': 2, 'май': 1})
collections модуліндегі Counter тізімді қабылдап, «мән → нешеу рет кездесті» деген сөздік қайтарады. Оның жоқ кілтке қатесі жоғы бөлек ыңғайлы: counts["қант"] 0 береді.
most_common(2) ең жиі кездесетін екі жұпты қайтарады. Мәтіндер мен журналдарға жеткенде, бұл сіз теретін бірінші пәрмен болады.
defaultdict: мән өзі пайда болады
кәдімгі сөздік → KeyError — 'нан'
defaultdict істеді: {'нан': 2}
Кәдімгі сөздік үшін plain["нан"] += 1 — қате: бірді қосу үшін алдымен бірдеңе болуы керек. defaultdict(int) мұндай жағдайда нөлді өзі қояды, сонда жол жұмыс істейді.
Бұл сиқыр емес, ереже: defaultdict әдепкі мәнді жасайтын функцияны қабылдайды. int 0 береді, list — бос тізім. Екіншісі жолдарды топтап жинағанда керек болады.
Сабақ картасы
Өз сөзіңізбен айтыңыз
Қарамай, дауыстап немесе қағазға жауап беріңіз. Жауаптар — сабақтың соңында.
- Жоқ кілтке жүгіну неге бос мән емес, қате?
max(prices, key=prices.get)нені қайтарады — бағаны ма, атауды ма?d["нан"] += 1жолындаdefaultdict(int)кәдімгі сөздіктен несімен өзгеше?
Жаттығу
Тапсырмаға дейінгі үш қысқа қадам: болжау, толықтыру, жөндеу. Жауаптары — сабақтың соңында, бірақ алдымен өзіңіз жауап беріңіз.
1. Болжаңыз. Бұл жол не басып шығарады?
prices = {"нан": 280, "тұз": 90}
print(prices.get("қант"), "тұз" in prices, len(prices))
2. Бос орынды толтырыңыз. ... орнына жоқ тауардың бағасы нөл деп саналатын әдепкіні қойыңыз.
prices = {"нан": 280, "тұз": 90}
print(prices.get("қант", ...))
3. Жөндеңіз. Анықтамалықта жоқ тауарда бағдарлама құлайды. Ол 0 деп жауап беретіндей етіңіз.
prices = {"нан": 280, "тұз": 90}
print(prices["қант"])
Тапсырма
Міндетті. Берілгені:
prices = {"нан": 280, "сүт": 620, "май": 1890, "тұз": 90}
Басып шығарыңыз: неше жазба бар; сүттің бағасын кілт арқылы; қанттың бағасын get арқылы әдепкісіз және 0 әдепкісімен; анықтамалықта қант пен тұз бар ма. Содан кейін қантты 450-ге қосып, неше жазба болғанын және қандай сомаға екенін; ең қымбат бағаны; атаулар тізімін басып шығарыңыз. Цикл жазбаңыз.
Күтілетін шығу:
жазба саны: 4
сүттің бағасы: 620
қанттың бағасы: None
қанттың бағасы әдепкімен: 0 теңге
қант бар: False | тұз бар: True
қосқаннан кейін: 5 жазба, сома: 3330
ең қымбат баға: 1890
атаулары: ['нан', 'сүт', 'май', 'тұз', 'қант']
Дайын болғаны: шығу жол-жолмен сәйкес келеді; жоқ кілт ешбір жерде тік жақшамен сұралмайды; атаулар тізімінде қант соңында тұр — демек, сөздік қосу ретін сақтайды.
Өз деректеріңізде. Баға анықтамалығын сөздікпен жинаңыз: атау → баға. Нағыз чекті былай сақтамайды — онда бірдей екі атау, саны, дана бағасы мен жеңілдік болады, ал сөздік екінші сондай кілт бойынша біріншісін жай ғана үстінен жазады. Атау бойынша баға іздеуге ол жарайды, бүгін біз дәл соны істеп жатырмыз. Мынаны басып шығарыңыз: бір тауардың бағасын, чекте жоқ тауардың бағасын (әдепкі мәнмен get арқылы), барлық бағаның сомасын, ең қымбат тауардың атауын және атау бойынша сұрыпталған жұптар тізімін.
Қалауыңызша.
- Апталық сатып алулар тізімі бойынша
Counterсанап, ең жиі үшеуін шығарыңыз. - Сабақтағы
cpiсөздігін алып, 2015-тен 2025-ке дейін бағалардың неше есе өскенін санаңыз. - Тізімді кілт қылып көріңіз — қате аласыз — онда не жазылғанын оқыңыз.
Жобада бұл қайда тұрады
Шолу өзінің басты құрылымын алады: жыл → мән. Теңге курсын күндер бойынша, баға индексін жылдар бойынша дерекқорға көшкенше дәл солай сақтаймыз.
Қарыздар. Сөздікті барлық кілттері бойынша аралауды әлі білмейміз — ол үшін цикл керек, келесі сабақ. Дерек әлі тек жадта тұр: бағдарламаны жаптыңыз — ол жоқ. Оның үстіне дереккөз бос жауап бергенде әлі қорғанбаймыз.
Жауаптар
Жауаптарды көрсету
Сұрақтарға
- Өйткені «дерек жоқ» пен «нөл» — екі басқа нәрсе, ал біріншісінің орнына екіншісін қою қауіпті: есеп үнсіз қате шығады. Кілттің болмауы қалыпты болғанда, ол үшін әдепкі мәнмен
getбар. - Атауды:
maxкілттерді аралайды, алkey=prices.getоларды қай мән бойынша салыстыруды айтады. Бағаны алу үшінmax(prices.values())керек. - Кәдімгі сөздікте
d["нан"] += 1кілттің болуын талап етеді, әйтпесеKeyError.defaultdict(int)алғаш жүгінген сәтте0қояды, сонда қосу жұмыс істейді.
Жаттығуға
None True 2. Жоқ кілт үшінgetқатенің орнынаNoneқайтарады,inTrueнеFalseдейді, алlenәріпті емес, жазбаны санайды.
None True 2
0.get-тің екінші аргументі — «кілт жоқ» жағдайына арналған жауап. Әрі жоқтықты немен санайтынын шешетін жер де сол: мұнда нөлмен, ал орташа бағаны есептегенде — енді олай емес.
prices = {"нан": 280, "тұз": 90}
print(prices.get("қант", 0))
0
KeyError: 'қант'. Тік жақша кілтті талап етеді де, ол болмаса құлайды;getсұрайды да, әдепкіні қайтарады. Біріншісі кілт міндетті түрде болуға тиіс жерде, екіншісі болмауы мүмкін жерде жарайды:
prices = {"нан": 280, "тұз": 90}
print(prices.get("қант", 0))
0
Пікірлер (0)
Пікір қалдыру үшін кіріңіз →
Әзірге пікір жоқ. Бірінші болыңыз.