Как перевести словарные имена из одного модуля в словарные ключи в другом модуле? - PullRequest
2 голосов
/ 20 декабря 2011

У меня есть набор значений, принадлежащих пользователям, которые будут параметрами для данной функции.Я буду сравнивать несколько групп, и у каждой из них будет свой набор предположений - примерно в 80% случаев они будут общими переменными (но не самими значениями).

Я буду добавлять новыепеременная чаще, чем новый пользователь, поэтому я бы предпочел связывать данные в виде словаря для каждой переменной.

Как лучше всего пройти данные предположений, чтобы составить словарь для данного пользователя?

Другими словами, отсюда:

assumptions.py

var_x = {'user_1': 10, 'user_2': 15, 'user_3': 12}
var_y = {'user_1': 1000, 'user_3': 950}   # nothing for user_2
var_z = {'user_1': 3, 'user_2': 2, 'user_3': 3}

здесь:

foobar.py

user = 'user_2'
<transpose>
user_dict = {'var_x':15, 'var_y':None, 'var_z':2}

Буду признателен за любой совет.Спасибо.

Ответы [ 4 ]

1 голос
/ 20 декабря 2011

Вот способ связать несколько словарей вместе (один со значениями по умолчанию, а другой с обновленными предположениями):

import UserDict

class Chainmap(UserDict.DictMixin):
    """Combine multiple mappings for successive lookups.

    For example, to emulate Python's normal lookup sequence:

        import __builtin__
        pylookup = Chainmap(locals(), globals(), vars(__builtin__))
    """

    def __init__(self, *maps):
        self._maps = maps

    def __getitem__(self, key):
        for mapping in self._maps:
            try:
                return mapping[key]
            except KeyError:
                pass
        raise KeyError(key)

    def keys(self):
        result = []
        seen = set()
        for mapping in self_maps:
            for key in mapping:
                if key not in seen:
                    result.append(key)
                    seen.add(key)
        return result

Для более полного интерфейса словаря см. Init.py # l754 "> http://hg.python.org/cpython/file/ab5d39caad6f/Lib/collections/init.py#l754

Класс ChainMap можно использовать следующим образом:

base_assumptions = dict(a1=10, a2=15, a3=30)

class FundClass:
    def __init__(self, fund, investor_assumptions)  #dict to be unpacked via '**' when passed
        combined_dict = ChainMap(investor_assumptions, base_assumptions)
        self.some_var = combined_dict['a1']
1 голос
/ 20 декабря 2011

Я думаю defaultdict из модуля collections - это то, что вы ищете.

Вот пример

from collections import defaultdict

# you must use `lambda` here as using just `None` will result with
# KeyError on undefined keys
fund_dict = defaultdict(lambda: None, {'assume01':15, 'assume03':2})
print fund_def['assume01']  # outputs 15
print fund_def['assume02']  # outputs None
print fund_def['assume03']  # outputs 2
0 голосов
/ 20 декабря 2011

при условии, что предположения находятся в том же каталоге, что и ваш скрипт

import assumptions
fund = "..."
fund_dict = {}
for d in dir(assumptions):
    element = eval("assumptions." + d)
    if isinstance(element, dict) and d[6:] == "assume": # in case there are other dictionaries in the file
        if fund in element:
            fund_dict[d] = element[fund]
        else:
            fund_dict[d] = None

# using your example:
# print fund_dict prints {'assume01': 15, 'assume02': None, 'assume03': 2}
0 голосов
/ 20 декабря 2011
assumptions = {'assume01': {'fund1':10, 'fund2':15, 'fund3':12},
               'assume02': {'fund1':1000, 'fund3':950},   
               'assume03': {'fund1':3, 'fund2':2, 'fund3':3}}

def fund_assumptions(fund):
    return dict((k, assumptions[k].get(fund)) for k in assumptions)

print fund_assumptions('fund2')
#prints {'assume02': None, 'assume03': 2, 'assume01': 15}
...