Како и када треба да користите Дефаултдицт у Питхон-у?

Увод у defaultdict у Питхон-у

У овом упутству ћете научити како да искористите defaultdict из Питхон-овог collections модула. Овај корисни алат вам помаже да ефикасније управљате грешкама типа KeyError када радите са речницима у Питхон-у.

Речник је у Питхон-у моћна уграђена структура података, која складишти информације у облику парова кључ-вредност. Кључеви се користе за приступ и проналажење одговарајућих вредности.

Међутим, када користите више речника у вашој Питхон скрипти, који се мењају током извршавања кода, често се можете сусрести са грешкама KeyError. Постоји више начина на које можете да се носите са овим грешкама.

У овом чланку ћете сазнати:

  • Шта су KeyError грешке и зашто настају
  • Како ефикасно управљати KeyError грешкама
  • Како користити defaultdict, специјализовану класу која наслеђује од уграђене класе dict, за ефикасније руковање кључевима који недостају

Кренимо!

Шта су то KeyError грешке у Питхон-у?

Приликом дефинисања речника у Питхон-у, морате бити сигурни да:

  • Су кључеви јединствени, тј. да се не понављају.
  • Када користите постојеће итерабле као кључеве, боље је користити непроменљиве колекције, као што су торке (tuples).

Кључ је важећи само ако постоји у речнику. У супротном, појавиће се грешка KeyError.

Погледајмо следећи речник books_authors, где су кључеви наслови књига, а вредности су имена аутора.

Можете пратити овај чланак у Питхон РЕПЛ-у.

books_authors = {
    'Deep Work':'Cal Newport',
    'Hyperfocus':'Chris Bailey',
    'Pivot':'Jenny Blake',
    'The Happiness Equation':'Neil Pasricha'
}
  

Можете користити кључ (наслов књиге) за приступ имену аутора.

books_authors['Hyperfocus']
# 'Chris Bailey'
  

Да бисте приступили свим паровима кључ/вредност у речнику, можете позвати методу items() на објекту речника:

for book,author in books_authors.items():
  print(f"'{book}' by {author}")
  
# 'Deep Work' by Cal Newport
# 'Hyperfocus' by Chris Bailey
# 'Pivot' by Jenny Blake
# 'The Happiness Equation' by Neil Pasricha
  

Ако покушате да приступите вредности за кључ који не постоји у речнику, Питхон интерпретер ће пријавити KeyError. До грешке KeyError долази када покушамо да приступимо вредностима за кључеве који не постоје, као што су ‘Grit’ и ‘non-existent-key’.

books_authors['Grit']
  
# ---------------------------------------------------------------------------
# KeyError                                  Traceback (most recent call last)
# <ipython-input-6-e1a4486f5ced> in <module>
# ----> 1 books_authors['Grit']
#
# KeyError: 'Grit'
  
books_authors['non-existent-key']
  
# ---------------------------------------------------------------------------
# KeyError                                  Traceback (most recent call last)
# <ipython-input-7-a3efd56f69e5> in <module>
# ----> 1 books_authors['non-existent-key']
#
# KeyError: 'non-existent-key'
  

Дакле, како се можемо носити са KeyError грешкама у Питхон-у?

Постоји неколико начина да се то уради, које ћемо размотрити у следећем одељку.

Како се носити са грешкама KeyError у Питхон-у

Погледајмо како да се носимо са KeyError грешкама користећи:

  • if-else условне исказе
  • try-except блокове
  • Метод .get() речника

#1. Коришћење if-else условних исказа

Један од најједноставнијих начина за руковање KeyError грешкама је коришћење if-else условних исказа.

У Питхон-у, if-else искази имају следећу општу синтаксу:

if condition:
  # do this
else:
  # do something else
  
  • Ако је услов тачан (True), извршавају се наредбе у телу if, и
  • Ако је услов нетачан (False), извршавају се наредбе у телу else.

У овом примеру, услов је провера да ли кључ постоји у речнику.

Ако кључ постоји, оператор in ће вратити True, и извршиће се тело if исказа, штампајући одговарајућу вредност.

key = 'The Happiness Equation'
if key in books_authors:
  print(books_authors[key])
else:
  print('Sorry, this key does not exist!')

# Output
# Neil Pasricha
  

Ако кључ не постоји у речнику, оператор in ће вратити False и извршиће се тело else исказа, штампајући поруку да кључ не постоји.

key = 'non-existent-key'
if key in books_authors:
  print(books_authors[key])
else:
  print('Sorry, this key does not exist!')

# Output
# Sorry, this key does not exist!
  

#2. Коришћење try-except исказа

Још један уобичајен начин руковања KeyError грешкама је коришћење try-except исказа у Питхон-у.

Погледајте следећи блок кода:

key = 'non-existent-key'
try:
  print(books_authors[key])
except KeyError:
  print('Sorry, this key does not exist!')
  
  • Блок try покушава да преузме вредност која одговара датом кључу.
  • Ако кључ не постоји, интерпретер пријављује KeyError, који се обрађује као изузетак унутар блока except.

#3. Коришћење .get() методе

У Питхон-у можете користити уграђену .get() методу речника за руковање кључевима који недостају.

Општа синтакса за коришћење .get() методе је dict.get(key,default_value), где је dict важећи објекат речника у Питхон-у.

  • Ако кључ постоји у речнику, .get() метода враћа вредност.
  • У супротном, враћа подразумевану вредност.

У овом примеру, кључеви су листа кључева за које желимо да приступимо вредностима. Пролазимо кроз листу кључева да бисмо преузели одговарајуће вредности из речника books_authors.

Користимо методу .get() са подразумеваном вредношћу „Не постоји“.

keys = ['Grit','Hyperfocus','Make Time','Deep Work']
for key in keys:
  print(books_authors.get(key,'Does not exist'))
  

У горњем коду:

  • За кључеве који постоје у речнику books_authors, метода .get() враћа одговарајуће вредности.
  • Када кључеви не постоје, у овом случају ‘Grit’ и ‘Make Time’, метода .get() враћа подразумевану вредност ‘Не постоји’.
# Output
# Does not exist
# Chris Bailey
# Does not exist
# Cal Newport
  

Сви горенаведени методи помажу нам да се носимо са KeyError грешкама. Међутим, они су опширни и захтевају од нас да експлицитно обрађујемо кључеве који недостају. Можете поједноставити овај процес коришћењем defaultdict уместо обичног речника.

defaultdict у Питхон-у

defaultdict је подкласа класе речника (dict). Дакле, наслеђује понашање Питхон речника. Поред тога, он такође природно управља недостајућим кључевима.

defaultdict је тип података контејнера који је уграђен у стандардну библиотеку Питхон-а, унутар модула collections.

Зато га морате увести у своје радно окружење:

from collections import defaultdict
  

Ево опште синтаксе за коришћење defaultdict:

defaultdict(default_factory)
  

Као атрибут default_factory можете навести објекат који се може позвати, као што су int, float или list. Ако не наведете вредност за default_factory, подразумевана вредност ће бити None.

Када кључ који тражите не постоји, позива се метода __missing__(), која из default_factory одређује подразумевану вредност, и враћа је.

Укратко:

  • У Питхон-у, defaultdict враћа подразумевану вредност када кључ не постоји.
  • Такође, додаје овај пар кључ-подразумевана вредност у речник, који затим можете да мењате.

Питхон defaultdict примери

Сада ћемо написати неколико примера да бисмо разумели како defaultdict функционише.

defaultdict у Питхон-у са подразумеваном целобројном вредношћу

Прво, увезите defaultdict из модула collections.

from collections import defaultdict
import random
  

Креирајмо defaultdict за цене.

prices = defaultdict(int)
  

Сада попуњавамо речник цена користећи ставке са листе воћа као кључеве. И насумично бирамо вредности из листе цена.

price_list = [10,23,12,19,5]
fruits = ['apple','strawberry','pomegranate','blueberry']

for fruit in fruits:
  prices[fruit] = random.choice(price_list)
  

Погледајмо парове кључ/вредност у речнику prices.

print(prices.items())
  
# dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10)])
  

Као и код обичног Питхон речника, можете приступити вредностима користећи кључеве:

prices['apple']
# 12
  

Сада покушајмо да приступимо цени воћа које не постоји, рецимо ‘orange’. Видимо да враћа подразумевану вредност нула.

prices['orange']
# 0
  

Ако одштампамо речник, видећемо да је нови кључ ‘orange’ додат са подразумеваном целобројном вредношћу нула.

print(prices.items())
  
# dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10), ('orange', 0)])
  

defaultdict у Питхон-у са листом као подразумеваном вредношћу

Дефинишимо students_majors као defaultdict за листе. Називи смерова су кључеви. А вредности су листе студената који похађају сваки од смерова, као што су математика, економија, информатика и др.

from collections import defaultdict
students_majors = defaultdict(list)
  

Ако покушамо да приступимо листи ученика која одговара смеру ‘Economics’, defaultdict враћа празну листу; нема KeyError грешке!

students_majors['Economics']
# []
  

Сада имамо празну листу која одговара смеру ‘Economics’. Дакле, можемо додати елементе у ову листу користећи метод .append().

students_majors['Economics'].append('Alex')
  

Направљен је унос за смер ‘Economics’ у defaultdict речнику students_majors.

print(students_majors)
  
# defaultdict(<class 'list'>, {'Economics': ['Alex']})
  

Можете додати још студената на листу за Економију, додати нове смерове и још много тога!

students_majors['Economics'].append('Bob')
students_majors['Math'].append('Laura')
print(students_majors)
  
# defaultdict(<class 'list'>, {'Economics': ['Alex', 'Bob'], 'Math': ['Laura']})
  

Закључак

Надам се да вам је овај чланак помогао да разумете како и када треба да користите defaultdict у Питхон-у. Након покретања примера кода из овог упутства, можете покушати да користите defaultdict као структуру података у вашим пројектима, где је то прикладно.

Ево резимеа онога што сте научили у овом упутству:

  • Када радите са Питхон речницима, често ћете наићи на KeyError грешке.
  • За управљање KeyError грешкама можете користити неколико опширних метода. Можете користити условне исказе, блокове try-except или методу .get(). Међутим, тип података defaultdict у модулу collections може поједноставити управљање овим грешкама.
  • Можете користити defaultdict(default_factory), где је default_factory важећа функција.
  • Када кључ не постоји у defaultdict, подразумевана вредност (добијена из default_factory) и кључ се додају у defaultdict.

Затим погледајте чланак о Питхон map функцији.