2013-11-24 3 views
0

Я хочу создать функцию, которая принимает словарь списков в качестве параметра и два других выхода, которые представляют значение ключа входного словаря.Изменение значения словаря на основе параметров

>>> where_clause_case_1({'a': [1, 2], 'b': [1, 2], 'c':[3, 2]}, 'b', 'c') 
{'a': [2], 'b': [2], 'c': [2]} 

Что функция должна делать, если ключевое значение b1 равно ключевому значению b2 в индексе, то функция возвращает весь словарь с каждым значением при этом определенный индекс, поэтому он остается неизменным. Но если b1 не равно b2 при индексе, функция удаляет этот индекс из всех списков. Я получаю сообщение об ошибке «builtins.KeyError:« c »для этого конкретного примера, и я не понимаю, почему.

def dictionary_change(my_dict, b1, b2): 
    i = 0 
    for key in my_dict: 
     if(my_dict[b1][i] == my_dict[b2][i]): 
      my_dict[key][i] = my_dict[key][i] 
     else: 
      my_dict[key][i] = [] 
     i += 1 
    return my_dict 
+0

Ваш пример вызова не определяет 'b1' и' b2' аргументы. Ваша петля над клавишей тоже не имеет никакого смысла. –

+0

Извините, я исправил это только сейчас. – user3014764

+0

Ваш образец все еще не имеет смысла; списки для 'a' и' b' идентичны, поэтому нет никаких различий, чтобы оправдать удаление первого значения из списка. –

ответ

1

Вы цикл по ключам словаря и увеличивают i одновременно. Это означает, что для 3-х клавиш i происходит от 0 до 2, но в каждом значении (0 и 1) есть только 2 элемента. Это приводит к ошибке вашего индекса.

Вместо этого используйте zip() в цикле по двум спискам, записывать индексы сохранить, а затем применить его ко всем значениям во всем словаре:

def where_clause_case_1(my_dict, b1, b2): 
    # build a set of indices to keep 
    keep = {i for i, (x, y) in enumerate(zip(my_dict[b1], my_dict[b2])) if x == y} 
    # build a new dictionary with kept indices 
    return {key: [v for i, v in enumerate(value) if i in keep] for key, value in my_dict.items()} 

Последняя строка создает новый словарь, используя Dict понимание ({key_expression: value_expression for variables in sequence}); в основном цикл, который строит ключи и значения для словаря. Он принимает ключи от my_dict, но изменяет значения. Каждое значение построено с использованием понимания списка; другой цикл. Здесь мы принимаем все исходные значения только, когда их индекс находится в наборе keep.

Без постижений, он бы выглядеть следующим образом:

def where_clause_case_1(my_dict, b1, b2): 
    # build a set of indices to keep 
    keep = set() 
    for i, (x, y) in enumerate(zip(my_dict[b1], my_dict[b2])): 
     if x == y: 
      keep.add(i) 

    # build a new dictionary with kept indices 
    retval = {} 
    for key, oldvalue in my_dict.items(): 
     retval[key] = newvalue = [] 
     for i, v in enumerate(oldvalue): 
      if i in keep: 
       newvalue.append(v) 
    return retval 

Демо:

>>> def where_clause_case_1(my_dict, b1, b2): 
...  # build a set of indices to keep 
...  keep = {i for i, (x, y) in enumerate(zip(my_dict[b1], my_dict[b2])) if x == y} 
...  # build a new dictionary with kept indices 
...  return {key: [v for i, v in enumerate(value) if i in keep] for key, value in my_dict.items()} 
... 
>>> where_clause_case_1({'a': [1, 2], 'b': [1, 2], 'c':[3, 2]}, 'b', 'c') 
{'a': [2], 'c': [2], 'b': [2]} 
>>> where_clause_case_1({'a': [1, 2], 'b': [1, 2], 'c':[3, 2]}, 'a', 'b') 
{'a': [1, 2], 'c': [3, 2], 'b': [1, 2]} 
+0

Можете ли вы объяснить заявление о возврате? Я не понимаю, что это делает. – user3014764

+0

А также, есть ли способ сделать это с петлей, подобной той, что я сделал? – user3014764

+0

Спасибо за объяснение, хотя, я новичок в python, поэтому я стараюсь учиться как можно больше. – user3014764

Смежные вопросы