Как изменить значения кортежа в словаре?

1

У меня есть этот словарь:

d = {'a': (1, 2, 'a'), 'b': (1, 2, 'b'), 'c': (2, 4, 'c'), 'd': (1, 3, 'd'), 'e': (0, 1, 'e'), 'f': (0, 1, 'f'), 'g': (1, 3, 'g'), 'h': (0, 1, 'h'), 'j': (1, 2, 'j'), 'i': (0, 1, 'i'), 'k': (-1, 0, 'k')}

Как можно вычесть значение на 1 для конкретной пары ключ/значение в этом словаре, если ключ соответствует параметру?

Например, я хочу вычесть значения ключа a на 1, чтобы он теперь отображал:

{'a': (0, 1, 'a')

Как я могу отредактировать значения этого конкретного ключа и уменьшить только целые числа на 1 при создании того же словаря снова?

Код до сих пор:

def matching(key_to_subtract): 
    for key, value in d.items():
        if key_to_subtract == key:


matching("a")

Желаемый результат:

{'a': (0, 1, 'a'), 'b': (1, 2, 'b'), 'c': (2, 4, 'c'), 'd': (1, 3, 'd'), 'e': (0, 1, 'e'), 'f': (0, 1, 'f'), 'g': (1, 3, 'g'), 'h': (0, 1, 'h'), 'j': (1, 2, 'j'), 'i': (0, 1, 'i'), 'k': (-1, 0, 'k')}
  • 1
    Возможный дубликат Python: изменение значения в кортеже
  • 0
    Кроме того, назначения для элементов в кортеже являются неизменяемыми (хотя объекты, на которые ссылаются эти назначения, сами могут быть изменяемыми).
Теги:

5 ответов

1

Поскольку tuple является неизменным, вы должны создать новый и связать его с ключом. Вам не нужно, однако, повторять dict для поиска данного ключа. В этом весь смысл dict:

def decrement(d, k): 
    # if k in d:  # if you are not certain the key exists
    d[k] = tuple(v-1 if isinstance(v, int) else v for v in d[k])
1

Вы не можете изменить содержимое кортежа. Так что вам нужно создать новый кортеж и назначить его на dict:

d = {'a': (1, 2, 'a'), 'b': (1, 2, 'b'), 'c': (2, 4, 'c')}
d['a'] = tuple( i - 1 if isinstance(i, int) else i for i in d['a'] )

# d become {'a': (0, 1, 'a'), 'b': (1, 2, 'b'), 'c': (2, 4, 'c')}
1

Поскольку кортежи являются неизменяемыми, вы должны снова перестроить кортеж и переназначить новый кортеж на тот же ключ, с которого вы его получили. Это может быть написано в 1-2 строки, используя понимание, но затруднит понимание, надеюсь, это поможет!

Использование выражений генератора

def matching(key_to_subtract):
    # generator expression force evaluated as tuple
    d[key_to_subtract] = tuple(item-1 if isinstance(item, int) else item for item in d.get(key_to_subtract)) 

Расширенная форма

d = {'a': (1, 2, 'a'), 'b': (1, 2, 'b'), 'c': (2, 4, 'c'), 'd': (1, 3, 'd'), 'e': (0, 1, 'e'), 'f': (0, 1, 'f'), 'g': (1, 3, 'g'), 'h': (0, 1, 'h'), 'j': (1, 2, 'j'), 'i': (0, 1, 'i'), 'k': (-1, 0, 'k')}

def matching(key_to_subtract): 

    buffer = [] # to build new tuple later from this list
    for item in d.get(key_to_subtract): # get the tuple and iterate over
        try:
            buffer.append(item - 1) # subtract 1
        except TypeError:
            buffer.append(item) # append directly if its not integer

    d[key_to_subtract] = tuple(buffer) # reassign the list as tuple

matching("a")
  • 1
    Это не понимание афаик. В Python нет выражения для понимания кортежей. Я считаю, что это выражение генератора
  • 1
    Они не являются фактически одинаковыми. Второй создает совершенно ложный объект list в памяти, и повторное append изменяет размер базового массива списков, возможно, несколько раз.
Показать ещё 1 комментарий
0

Исходя из вашего вопроса, я предлагаю другой подход из вашего кода. Причина в том, что d.items() создает представление, которое хорошо для проверки, но не для обновления кода.

Поэтому я предлагаю использовать d.keys() для поиска экземпляра key_to_subtract. Затем измените кортеж на список (или вы можете использовать другой метод нарезки кортежа в нужной позиции, затем добавьте новое значение, которое может быть быстрее в случае большого кортежа), а затем замените этот ключ новым значением (после изменив его обратно из списка в кортеж):

def matching(key_to_subtract):
    #check for key_to_subtract
    #if found
    if key_to_subtract in d.keys():
        #change to list
        lst_val = list(d[key_to_subtract])

        #subtract the two values
        lst_val[0]-=1
        lst_val[1]-=1

        #change back to tuple
        tuple_val = tuple(lst_val)

        #replace the old value of the same key with the new value
        d[key_to_subtract] = tuple_val

на основе функций в: https://docs.python.org/3.7/library/stdtypes.html#dict-views

-2

Вы можете сделать это так, как кортежи являются неизменными объектами.

d = {'a': (1, 2, 'a'), 'b': (1, 2, 'b'), 'c': (2, 4, 'c'), 'd': (1, 3, 'd'), 'e': (0, 1, 'e'), 'f': (0, 1, 'f'), 'g': (1, 3, 'g'), 'h': (0, 1, 'h'), 'j': (1, 2, 'j'), 'i': (0, 1, 'i'), 'k': (-1, 0, 'k')}

def change_value_by_key_pos(data, key, pos, step):
    for k,v in data.items():
        if k == key:
            list_items = list(data[key])
            list_items[pos] = list_items[pos]+step
            data[key] = tuple(list_items)
    return data
data = change_value_by_key_pos(d,'a',1,1)
print(data)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню