Вопрос об автоматизации скучных вещей: глава 5 - PullRequest
1 голос
/ 25 апреля 2020

Я новичок в программировании, и в настоящее время я работаю с Automate the Boring Stuff с Python, 2-е издание. В Главе 5 есть практический вопрос, который включает в себя создание инвентаря Fantasy Game с использованием словарей. Я выполнил задачу, используя ответы других, однако я не понимаю определенную часть кода c.

Этот код означает добавление нового списка «dragonLoot» в текущий инвентарь, который является словарем «inv». Вот мой код:

def displayInventory(inventory):
    print("Inventory:")
    item_total = 0
    for k, v in inventory.items():
         item_total = item_total + v
         print(str(v) + " " + k)
    print("Total number of items: " + str(item_total))

def addToInventory(inventory, addedItems):
    for i in addedItems:
        inventory.setdefault(i, 0)
        inventory[i] = inventory[i] + 1
    return inventory



inv = {'gold coin': 42, 'rope': 1}
dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby']
inv = addToInventory(inv, dragonLoot)

displayInventory(inv)

Мой вопрос относится к этому разделу c:

def addToInventory(inventory, addedItems):
for i in addedItems:
    inventory.setdefault(i, 0)
    inventory[i] = inventory[i] + 1
return inventory

При вводе «inventory.setdefault (i, 0)", а затем " инвентарь [i] = инвентарь [i] + 1 ", как этот код позволяет добавлять список в словарь?

Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2020

Это защита от KeyError, если ключ словаря еще не был установлен. Вы также можете использовать defaultdict из модуля коллекций в стандартной библиотеке.

Примите во внимание следующее

inventory = {}
addedItems = ['1', '2', '3']
addToInventory(inventory, addedItems)

Вы получите правильный вывод, даже если инвентарь был пуст. Это потому, что setdefault гарантирует, что ключ будет создан со значением по умолчанию, если он еще не существует. Это избавляет вас от необходимости использовать оператор if/then о том, находится ли ключ уже в диктанте.

{'1': 1, '2': 1, '3': 1}

Теперь попробуйте ту же самую функцию без строки setdefault

def addToInventory(inventory, addedItems):
    for i in addedItems:
        inventory[i] = inventory[i] + 1
    return inventory

inventory = {}
addedItems = ['1', '2', '3']
addToInventory(inventory, addedItems)

=== Output: ===
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-137-8302116925c5> in <module>
      6 inventory = {}
      7 addedItems = ['1', '2', '3']
----> 8 addToInventory(inventory, addedItems)

<ipython-input-137-8302116925c5> in addToInventory(inventory, addedItems)
      1 def addToInventory(inventory, addedItems):
      2     for i in addedItems:
----> 3         inventory[i] = inventory[i] + 1
      4     return inventory
      5 

KeyError: '1'

Теперь посмотрим, что произойдет, если вы используете defaultdict.

from collections import defaultdict
def addToInventory(inventory, addedItems):
    for i in addedItems:
        inventory[i] = inventory[i] + 1
    return inventory

inventory = defaultdict(int)
addedItems = ['1', '2', '3']
addToInventory(inventory, addedItems)

=== Output: ===
Out[143]: defaultdict(int, {'1': 1, '2': 1, '3': 1})
0 голосов
/ 25 апреля 2020

Давайте отключим функцию l oop in addToInventory. Сначала у нас есть

inventory.setdefault(i ,0)

Эта инструкция означает «если ключа i еще нет в словаре inventory, установите его на 0. Это - в данном случае (потому что мы не используем возвращаемое значение setdefault) - эквивалентно

if i not in inventory.keys():
    inventory[i] = 0

Далее идет эта инструкция

inventory[i] = inventory[i] + 1

Это, в основном, увеличение , т.е. добавление 1 к inventory значению для ключа i.

Объяснено иначе, что for l oop «для каждого элемента в addedItems, установите соответствующее значение в словаре inventory на ноль, если его еще нет, затем увеличьте его».


После того, как вы закончите с этой книгой, вы можете Вы можете потратить некоторое время на проверку Python модуля collections стандартной библиотеки, особенно defaultdict и Counter, который бы намного лучше подходил для этой логики. c вы пытаетесь реализовать.

...