Как назначить некоторые ключевые значения из функции, возвращающей словарь в другой словарь? - PullRequest
0 голосов
/ 03 мая 2020

у меня три словаря; фрукты, овощи и всего. Два словаря модифицированы в двух разных функциях; и те же самые два словаря являются подмножеством всего словаря. Функции возвращают измененные словари. Как я могу назначить часть ключей в возвращаемом словаре функции части в общем словаре, как показано в MWE.

MWE

def get_fruits(x):
    fruits = {'apples'       : 0, 'oranges'      : 0, 'bananas'      : 0, 'strawberries' : 0, 'blueberries'  : 0}
    if x == 'apples':
        fruits['apples'] += 1
    elif x == 'oranges':
        fruits['oranges'] += 1
    elif x == 'bananas':
        fruits['bananas'] += 1
    return fruits
def get_vegetables(x):
    vegetables = {'carrots'   : 0, 'potatoes'  : 0, 'onions'    : 0, 'garlics'   : 0, 'gingers'   : 0}
    if x == 'carrots':
        vegetables['carrots'] += 1
    elif x == 'potatoes':
        vegetables['potatoes'] += 1
    elif x == 'onions':
        vegetables['onions'] += 1
    return vegetables
total = {
            'apples'       : 0, 'oranges'      : 0, 'grapes'       : 0, 'bananas'      : 0, 'strawberries' : 0, 'blueberries'  : 0,
            'carrots'      : 0, 'potatoes'     : 0, 'onions'       : 0, 'gingers'      : 0, 'cucumbers'    : 0, 'garlics'      : 0
        }

total['apples'], total['oranges'], total['bananas'] = get_fruits('apples')['apples','oranges','bananas']

В других слова, мне нужна функция get_fruits для обновления только трех ключей; яблоки, апельсины и бананы; как это можно сделать в Python?

Ответы [ 3 ]

0 голосов
/ 03 мая 2020

Общий ответ на вопрос - функция update, которая обновляет один словарь значениями из другого (оставляя другие пары key: value без изменений).

>>> total = {'apples': 0, 'oranges': 0, 'carrots': 0, 'onions': 0}
>>> total.update({'apples': 1, 'oranges': 2})
>>> total
{'apples': 1, 'oranges': 2, 'carrots': 0, 'onions': 0}

Таким образом, вы можете сделать:

total.update(get_fruits('apples'))

для обновления total всеми значениями, возвращаемыми get_fruits('apples').

Чтобы отфильтровать словарь, вы можете сделать понимание, например:

{k: v for k, v in get_fruits('apples').items() if k in {'apples', 'oranges', 'bananas'}}

Обратите внимание, что ваши функции get_fruits и get_vegetables на самом деле не выполняют то, что вы описываете для них; они создают словари с нуля каждый раз, а не модифицируют их, так что вы всегда просто получите ответ, содержащий 1 из того, что вы передали в качестве параметра. Чтобы изменить словарь и увеличить счетчик, вы должны каждый раз передавать один и тот же словарь в качестве аргумента, например:

from collections import defaultdict
from typing import Dict

def add_item(item: str, inventory: Dict[str, int]) -> None:
    inventory[item] += 1

fruits: Dict[str, int] = defaultdict(int)
vegetables: Dict[str, int] = defaultdict(int)

add_item('apples', fruits)
add_item('apples', fruits)
add_item('carrots', vegetables)

total: Dict[str, int] = {}
total.update(fruits)
total.update(vegetables)
# total: 2 apples, 1 carrots

et c.

0 голосов
/ 03 мая 2020

Есть неплохие ответы выше. Если я, возможно, понял ваш запрос, то вы пытаетесь сделать что-то вроде следующего?

total = {'fruits': {'apples' : 0, 
                    'oranges': 0, 
                    'bananas': 0, 
                    'strawberries' : 0, 
                    'blueberries'  : 0,
                   },
         'vegetables': {'carrots': 0, 
                        'potatoes'  : 0, 
                        'onions'    : 0, 
                        'garlics'   : 0, 
                        'gingers'   : 0,
                       }
        }

def get_fruits(x):
    if x in ('apples', 'oranges', 'bananas'):
        total['fruits'][x] += 1

def get_vegetables(x):
    if x in ('carrots', 'potatoes', 'onions'):
        total['vegetables'][x] += 1


if __name__ == "__main__":

    fruits = ['apples', 'oranges', 'bananas']

    for fruit in fruits:
        get_fruits(fruit)

    for fruit in fruits:
        print(total['fruits'][fruit])

# You should see an increase in the fruit count

    for fruit in fruits:
        get_fruits(fruit)

    for fruit in fruits:
        print(total['fruits'][fruit])```
0 голосов
/ 03 мая 2020

Я бы предложил просто использовать collections.Counter

Позволяет также упростить ваш пример:

  • удалить ключевые примеры if / else
  • сделать фрукты / овощи глобальными устанавливает
  • использовать счетчик, чтобы мы могли сделать x += y
from collections import Counter

FRUITS = {'apples', 'oranges', 'bananas', 'strawberries', 'blueberries'}
VEGETABLES = {'carrots', 'potatoes', 'onions', 'garlics', 'gingers'}

def get_fruits(x):
    ret = Counter()
    if x in FRUITS:
        ret[x] += 1
    return ret

def get_vegetables(x):
    ret = Counter()
    if x in VEGETABLES:
        ret[x] += 1
    return ret

total = Counter({x: 0 for x in FRUITS | VEGETABLES})
total += get_fruits('apples')

Есть и другие изменения, которые также могут быть сделаны, но я предполагаю, что вы уже упростили некоторый код, который использует тот факт, что здесь есть разные функции.

...