Речници¶
Сега ще представим нов тип структурирани данни, т.е. събиране, което е доста различно от тези, които сме срещали досега.
Да предположим, че трябва да напишем програма, която отговаря на въпроси за възрастта на даден човек. Имената и възрастите на лицата са ни известни, например Мария е на 14 години, Михаил 15, Даниел също 15 и Матилда 16 (действителните данни биха били по-обширни, но това е само пример).
Можем да разрешим този проблем, като поставим имената в единия низ, а възрастите в другия. С тези два низа можем да използваме цикъл, за да търсим дадено име в низа на името и когато го намерим, използваме същия индекс за достъп и отпечатване на подходящата възраст.
Както виждаме, колекциите, които вече познаваме, могат да ни послужат и в този случай. За този тип задачи обаче има колекция, в която данните се записват по по-прозрачен начин, а необходимите данни се намират по-лесно и по-ефективно. Нека разгледаме друго решение:
Колекция от формата {‘Mary’:14, ‘Michael’:15, ‘Daniel’:15, ‘Matilda’:16} се нарича речник. Можем да видим, че речник може да бъде настроен подобно на низ и списък - чрез изброяване на разделени със запетая елементи. Елементите от речника се изписват между къдравите скоби {}. Всеки елемент се състои от две части, между които има двоеточие:. Първата част на елемента се нарича ключ, а втората - стойността. Например за ключа „Mary“ съответната стойност е 14 и т.н.
Ние използваме речници за бързо и лесно да получим стойност за даден ключ. В нашия пример намерихме възрастта за дадено име в речника. В низовете и списъците по подобен начин извличаме стойността на елемента чрез поредния номер (индекс) на този елемент. Можем да кажем, че ключът в речника играе ролята, която индексът играе в низовете и списъците. Съществената разлика между речниците от една страна, и низовете и списъците, от друга, е, че в речника ключът може да бъде от всякакъв неизменяем тип (цяло число, реално число, низ,…), докато сте в низа или изброите индексите трябва да са цели числа, започващи от 0.
Изграждане на речник¶
Ние също можем да изградим речник, като изчислим. Правим това, като вмъкваме нови двойки ключ-стойност в речника и след това променяме стойността за даден ключ, ако е необходимо.
В следващия пример стартовият низ съдържа имената на футболните клубове, спечелили Купата на европейските шампиони (или Шампионската лига на УЕФА) от 1956-2019 г. Въз основа на тази информация ще формираме речник, в който ще запазим броя спечелени първенства за всеки клуб. Ето как можем да го направим.
В началото оформяме празен речник с номера_запис. За всеки клуб в списъка на шампионите, първо проверяваме дали клубът вече съществува в речника с числата. Ако е така, ние добавяме едно към броя на заглавията на клуба и ако не е, добавете клуба към речника с едно спечелено заглавие.
В края на броенето преминаваме през речника с помощта на цикъл и отпечатваме ключовете и стойностите от този речник.
Един от начините за съкращаване на тази програма е използването на функцията (метод) get, която е част от всеки речник и се нарича с dictionary_name.get (ключ, default_value). Както виждаме, тази функция има два аргумента. Първият аргумент е ключът, за който имаме нужда от стойността. В случай, че ключът съществува в речника, функцията get връща стойността, съответстваща на този ключ, и ако ключът не е в речника, функцията връща стойността на втория си аргумент. Така например вместо това
if club in num_titles:
num_titles[club] += 1
else:
num_titles[club] = 1
можем да напишем това
num_titles[club] = num_titles.get(club, 0) + 1
и ефектът е същият. В този пример *num_titles.get(club, 0)* връща броя на заглавията на даден клуб, ако този клуб вече е в речника, или 0, ако все още не е в речника. И в двата случая 1 трябва да се добави към тази стойност и да се съхранява в речника като новия брой заглавия за този клуб.
Задачи за упражнения¶
Задача - цени на хранителни стоки
Цените в един магазин са:
Хляб: 1 (за хляб - половин килограм)
Мляко: 0,8 (на литър)
Яйце: 0,08 (за парче)
Пилешки гърди: 7,3 (на килограм)
Ябълки: 2,2 (за килограм)
Домати: 1 (на килограм)
Поставете тази информация в речник и след това завършете програмата, като заредите името на дадена храна и покажете цената на тази храна или информация, че тя не е налична.
Задача - отсъствие
Имената на студентите, които отсъстваха от класа, бяха дадени в низ. Всяка поява на едно име представлява отсъствие от един клас. Попълнете програмата, така че тя изчислява и отпечатва колко класове е пропуснал всеки ученик.
За да ви помогнем да проверите програмата си, ето очаквания резултат: за данните, дадени в низа absent, трябва да получите, че Джеймс има 4 отсъствия, Мая 3, Александър 2 и Виолет, Марк, Франки, Питър, Рони и Оливър по едно(не е задължително в този ред).
Задача - състояние на запасите
Дават се покупки и продажби на стоки под формата на пакет от двойки. Във всяка двойка първият елемент е името на стоките, а вторият е промяната на състоянието на запасите. Например, двойка („сирене“, -1,5) означава, че наличното количество сирене е намаляло с 1,5 (толкова много сирене е продадено).
Завършете програмата, която изчислява и отпечатва състоянието след тези промени, въз основа на дадените промени в състоянието. Да приемем, че няма запаси в началото.
Проверете резултата: при дадената информация трябва да получите следното (в какъвто и да е ред)
сирене 18.5
мляко 297
брашно 985
яйца 1988
риба 47
В тази задача най-важната част от програмата е преминаването през всички двойки. За по-голяма яснота, ние веднага разопаковаме всяка двойка от комплекта changes до променливи good, change.