如何更新未知状态的深层嵌套字典?

时间:2016-11-17 06:42:48

标签: python python-3.x dictionary

我有很高的字典3级。我不知道密钥是否存在。如果它们存在,我需要更新该值。如果他们不存在我需要添加密钥和&值。

这是我的代码......但这是一团糟。必须有一个更清洁,更优雅的方式来做到这一点???

建议???

def update_balances_cache(client_name, exchange_name,
                      api_key_nickname, balances,
                      time_checked):

from settings import CACHE

'''
Dictionary structure:
balances = {client_name: {exchange_name: {api_key_nickname: {balances}
                                        }
                             }
               }

CACHE is a class instance holding shared variables between modules.

'''

api_key_level = {api_key_nickname: balances}

exchange_level = {exchange_name: api_key_level}


with CACHE.vlock:
    try:
        # is there a client in the dictionary?
        CACHE.BALANCES_CACHE[client_name]
    except:
        # add client level to dictionary
        CACHE.BALANCES_CACHE[client_name] = exchange_level
        CACHE.BALANCES_CACHE[client_name][exchange_name][api_key_nickname]['last check time'] = time_checked

        return

    # there is a client in the dictionary.  Is the exchange there?
    try:
        CACHE.BALANCES_CACHE[client_name][exchange_name]
    except:
        # add the exchange
        CACHE.BALANCES_CACHE[client_name][exchange_name] = exchange_level
        CACHE.BALANCES_CACHE[client_name][exchange_name][api_key_nickname]['last check time'] = time_checked

        return

    # there is a client & exchange.
    CACHE.BALANCES_CACHE[client_name][exchange_name][api_key_nickname] = api_key_level
    CACHE.BALANCES_CACHE[client_name][exchange_name][api_key_nickname]['last check time'] = time_checked

return

2 个答案:

答案 0 :(得分:2)

试试这个

def updatedict(a,b):
  for key in b:
      if not key in a or type(a[key]) != dict or type(b[key])!=dict:
          a[key]=b[key]
      else:
          updatedict(a[key],b[key])
x={"a":{"b":{"c":"d"}}}
y={"a":{"b":{"e":"f","c":"d1"},"g":{"h":"i"}},"j":{"k":{"l":"m"}}}
updatedict(x,y)
print(x)

生成的更新x值

{'j': {'k': {'l': 'm'}}, 'a': {'b': {'c': 'd1', 'e': 'f'}, 'g': {'h': 'i'}}}

答案 1 :(得分:0)

使用集合模块中的defaultdict,如果适合您的情况,请试用

from collections import defaultdict
nested_dict = lambda: defaultdict(nested_dict) # this create nested dict with defaultdict

BALANCES_CACHE = nested_dict()
BALANCES_CACHE['client_name']['exchange_name']['api_key_nickname']['last check time'] = 1234
BALANCES_CACHE['client_name']['exchange_name']['api_key_nickname2']['last check time'] = 5678

>>> BALANCES_CACHE['client_name']['exchange_name']['api_key_nickname']['last check time']
1234
>>> BALANCES_CACHE['client_name']['exchange_name']['api_key_nickname2']['last check time']
5678

# default to defaultdict type
>>? BALANCES_CACHE['client_name']['exchange_name']['api_key_nickname2']['blablabla']
defaultdict(<function <lambda> at 0x000000001C66A128>, {})

要根据您的情况将其修复为深度4,请尝试以下操作,希望它能正常工作

from collections import defaultdict
from settings import CACHE
# this set 4 level depth dict with last level default to int, change accordingly
CACHE.BALANCES_CACHE = defaultdict(lambda:defaultdict(lambda:defaultdict(lambda:defaultdict(int))))

def update_balances_cache(client_name, exchange_name,
                      api_key_nickname, balances,
                      time_checked):

    # from settings import CACHE # move outside function
    api_key_level = {api_key_nickname: balances}
    exchange_level = {exchange_name: api_key_level}

    with CACHE.vlock:
        # update dict
        CACHE.BALANCES_CACHE[client_name].update(exchange_level)
        CACHE.BALANCES_CACHE[client_name][exchange_name].update(exchange_level) # seems like should be api_key_level ?
        CACHE.BALANCES_CACHE[client_name][exchange_name][api_key_nickname].update(api_key_level) # seems no need ?

        CACHE.BALANCES_CACHE[client_name][exchange_name][api_key_nickname]['last check time'] = time_checked