Я хочу заменить значения в словаре 1 соответствующими значениями из словаря 2

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

# Matches proteins to corresponding drug ids #
dict1 = {'Protein 1' : '001, 002, 003', 'Protein 2' : '003, 004', 'Protein 3' : '002'}

# Matches drug ids with drug names #
dict2 = {'001' : 'Drug1', '002' : 'Drug2', '003' : 'Drug3', '004' : 'Drug4'}

Я хотел бы сопоставить соответствующие названия лекарств из dict2, чтобы заменить идентификаторы лекарств в dict 1, чтобы результат выглядел следующим образом:

output_dict = {'Protein 1' : ['Drug1', 'Drug2', 'Drug3'], 'Protein 2' : ['Drug3', 'Drug4'], 'Protein 3' : ['Drug2']}
1
kyrE 30 Апр 2019 в 18:48

3 ответа

Лучший ответ

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

dict1 = {'Protein 1' : '001, 002, 003', 'Protein 2' : '003, 004', 'Protein 3' : '002'}

dict1 = {k : v.split(", ") for k,v in dict1.items()}

Теперь у нас есть список строк в качестве значений, что имеет больше смысла.

>>> dict1
{'Protein 1': ['001', '002', '003'],
 'Protein 2': ['003', '004'],
 'Protein 3': ['002']}

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

# Matches proteins to corresponding drug ids #
dict1 = {'Protein 1' : ['001', '002', '003'], 'Protein 2' : ['003', '004'], 'Protein 3' : ['002']}

# Matches drug ids with drug names #
dict2 = {'001' : 'Drug1', '002' : 'Drug2', '003' : 'Drug3', '004' : 'Drug4'}

dict3 = {k : [dict2.get(x,x) for x in v] for k,v in dict1.items()}

Результат:

>>> dict3
{'Protein 1': ['Drug1', 'Drug2', 'Drug3'],
 'Protein 2': ['Drug3', 'Drug4'],
 'Protein 3': ['Drug2']}
3
Jean-François Fabre 30 Апр 2019 в 17:16

Этот код вернет вывод, который вы просили:

# Matches proteins to corresponding drug ids #
dict1 = {'Protein 1': ['001, 002, 003'], 'Protein 2': ['003, 004'], 'Protein 3': ['002']}

# Matches drug ids with drug names #
dict2 = {'001': 'Drug1', '002': 'Drug2', '003': 'Drug3', '004': 'Drug4'}


def string_replace_bulk(string, rules):
    result = string

    for old, new in rules.items():
        result = result.replace(old, new)

    return result


def weird_string_replace(src, rules):
    return [string_replace_bulk(s.strip(), rules) for s in src.split(',')]


def weird_list_replace(src, rules):
    result = {}
    for key, value in src.items():
        result[key] = []
        for item in value:
            result[key].extend(weird_string_replace(item, rules))

    return result


output_dict = weird_list_replace(dict1, dict2)

print(output_dict)

Результат:

{'Protein 1': ['Drug1', 'Drug2', 'Drug3'], 'Protein 2': ['Drug3', 'Drug4'], 'Protein 3': ['Drug2']}

Постскриптум Это действительно странный формат ввода, лучше с ним что-то сделать.

1
Olvin Roght 30 Апр 2019 в 16:34

Однострочный:

>>> dict1 = {'Protein 1' : '001, 002, 003', 'Protein 2' : '003, 004', 'Protein 3' : '002'}
>>> dict2 = {'001' : 'Drug1', '002' : 'Drug2', '003' : 'Drug3', '004' : 'Drug4'}
>>> {k: map(dict2.get, v.split(", ")) for k, v in dict1.items()}
{'Protein 1': ['Drug1', 'Drug2', 'Drug3'], 'Protein 2': ['Drug3', 'Drug4'], 'Protein 3': ['Drug2']}

Для каждого списка кодов "001, ..." в dict1 разбейте строку и сопоставьте коды со значениями в dict2

1
jferard 30 Апр 2019 в 20:43