2011-12-20 2 views
2

У меня есть набор значений, принадлежащих пользователям, которые будут параметрами для данной функции. Есть несколько групп, которые я буду сравнивать, и каждый из них имеет свой собственный набор предположений - около 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} 

Любой совет будет б e очень оценили. Благодарю.

ответ

0
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} 
+0

Это удобный подход. Моя единственная проблема заключается в том, масштабируется ли она без редактирования файла напрямую. Новые переменные 'предполагаю ...' часто появляются, что мне нужно добавить. Я все еще очень новичок в программировании, но я надеюсь включить этот модуль «допущений» в среду GUI для редактирования допущений, и я не знаю, повлияет ли на него словари, встроенные в другой словарь. Попробуем. Большое спасибо. – hommel

+0

@DolphinTsar Хорошо разделить данные и программную логику. Предположения - это данные, но определения переменных являются частью программной логики –

1

Я думаю, 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

Почему 'defaultdict'? – Blender

+0

@Blender Я обновил свой ответ с помощью кода примера – lig

1

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

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'] 
0

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

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

Ahh! Это то, что я пытался сделать. Я был пойман, пытаясь ссылаться на модуль допущений с помощью подхода 'module.object', но не использовал' eval', поэтому получал ошибку, что итерационная переменная не была найдена в 'предположениях'. Попробуй, когда я вернусь домой. Благодаря! – hommel