2015-07-10 3 views
1

Скажет у меня есть два Dict, как это,Бесконечного цикл в то время как итерация словаря Python

data_dict = {'A1': 5, 'A2': 10, 'A3': 15} 

и

formula_dict = {'A4': 'A1*A3', 'A6': 'A1+A5+A2', 'A5': 'A1+A2+A3+A4'} 

Я перебор беспересадочных формул Dict и вычисление выражения, как он получает, а затем снова добавив обратно к копии data_dict, пока вся формула не будет полностью оценена. Логика отлично работает, но вызывает бесконечный цикл. Как разрешить этот бесконечный цикл?

def update_some(convert_dict, in_dict): 
    in_dict_update = in_dict.copy() 
    convert_dict_update = convert_dict.copy() 
    while convert_dict_update: 
     for k, v in list(convert_dict_update.items()): 
      print(convert_dict_update.items()) 
      try: 
       return_value = eval(v, in_dict) 
       in_dict_update[k] = return_value 
       convert_dict_update.pop(k) 
      except NameError: 
       continue 

      update_some(convert_dict_update, in_dict_update) 
     print(in_dict_update) 
    print('After ', convert_dict_update) 
    print(in_dict_update) 
    return in_dict_update 


# update_some(converted_dict, data_dict) 

печати Также в in_dict_update печатает ненужная ключ, значение пары, как некоторые __builtins__

+0

@Hacketo, почему? 'len (convert_dict_update)' false (равно '0') тогда и только тогда, когда' convert_dict_update' является ложным (это пустой 'dict'). – werkritter

ответ

2

Ваш вызов eval использует in_dict в качестве глобального Словаре, который испытывает недостаток стандартных глобальных атрибутов. Таким образом, python добавляет их для вас. Попытка:

return_value = eval(v, None, in_dict) 

Однако, вы должны попытаться уменьшить сложность своей рекурсии. Я бы предложил:

def update_some(convert_dict, in_dict): 
    in_dict_update = in_dict.copy() 
    skipped_values = {} 
    for k,v in convert_dict.items(): 
     try: 
      return_value = eval(v, None, in_dict_update) 
     except NameError: 
      skipped_values[k] = v 
     else: 
      in_dict_update[k] = return_value 
    if skipped_values: 
     in_dict_update = update_some(skipped_values, in_dict_update) 
    return in_dict_update 
Смежные вопросы