Почему Python (3.7) продолжает переопределять пары ключ: значение в моем вложенном словаре? - PullRequest
0 голосов
/ 15 января 2019

Я хочу предвосхитить это, сказав, что я повторил дух кода в терминале python, написав:

A = {}
A["Q"] = {}
A["Q"]["creation"] = {}
A["Q"]["creation"]["reactants_1"] = ["R1","R2"]

печать A дает то, что можно ожидать:

{"Q" : {"creation" : {"reactants_1" : ["R1","R2"]}}}

затем добавление:

A["Q"]["creation"]["reactants_2"] = ["R3","R4"]

выходы:

{"Q" : {"creation" : {"reactants_1" : ["R1","R2"], "reactants_2" : ["R3","R4"]}}}

Однако у меня есть функция, показанная ниже, которая при правильном запуске назначает первые несколько пар ключ: значение, но когда она переходит на второе значение x, она заменяет первую пару ключ: значение, которую она написала ранее, новой, несмотря на ключ другой.

используя приведенный выше пример, мы получим только:

{"Q" : {"creation" : {"reactants_2" : ["R3","R4"]}}}

Реакции - это массив, содержащий такие вещи, как «e + e + p = e + H_1» в формате:

["e+e+p=e+H_1", "e+e+p=e+H_2",...,"e+H_10=e+e+p"]

Вид - это массив типа:

[["e", 100000],["p", 100000],...]

где сейчас мы заботимся только о струнной части.

diff_input - пустой словарь, начинающийся с

Reaction_const содержит, для каждой реакции, левую и правую стороны отдельно - замеченные как [x] [0] [0] и [x] [0] [1] в начале функции, а также некоторую другую информацию, которая является пока не важно.

rate_names - это массив уникальных идентификаторов для каждой реакции, которые я могу использовать позже, следовательно, используя словарный подход.

операторы печати - все, что я пытаюсь выяснить, почему это не работает

def rate_eqns(diff_input, reactions, species, reactions_const, 
          rates_names):

for x in range(len(reactions)):
    # for each reaction
    # split the left and right hand side up into lists of their 
    # respective species involved for counting later

    print("reaction: " + str(x) + " " + str(reactions[x]))

    species_lhs = reactions_const[x][0][0].split('+')
    print("LHS = " + str(species_lhs))

    species_rhs = reactions_const[x][0][1].split('+')

    for y in range(len(species)):  
        # For each species, create a sub-dictionary
        diff_input[species[y][0]] = {}

        # create sub-dictionaries in each species for creation, destruction and preservation/neutral paths
        diff_input[species[y][0]]["destruction"] = {}
        diff_input[species[y][0]]["creation"] = {}
        diff_input[species[y][0]]["balanced"] = {}

        # check if species occurs in each reaction

        if species[y][0] in reactions[x][0]:

            # if you start with more of it than you finish its destruction
            if species_lhs.count(species[y][0]) > species_rhs.count(species[y][0]):

                # if true: add an entry to the dictionary which holds the reaction identifier
                # bound to the destruction/creation/balanced identifier bound to the species identifier.
                print("species:" + str(species[y][0]) + " found net loss from reactants")
                print("LHS = " + str(species_lhs))
                print("RHS = " + str(species_rhs))
                print("reaction designation = " + str(rates_names[x]) + " Destruction of species")
                print("-------------")
                diff_input[species[y][0]]["destruction"][rates_names[x]] = species_lhs

            elif species_lhs.count(species[y][0]) == species_rhs.count(species[y][0]):
                print("species:" + str(species[y][0]) + " found no change in number")
                print("LHS = " + str(species_lhs))
                print("RHS = " + str(species_rhs))
                print("reaction designation = " + str(rates_names[x]) + " preservation of species")
                diff_input[species[y][0]]["balanced"][rates_names[x]] = species_lhs

            elif species_lhs.count(species[y][0]) < species_rhs.count(species[y][0]):
                print("species:" + str(species[y][0]) + " found net gain from reactants")
                print("LHS = " + str(species_lhs))
                print("RHS = " + str(species_rhs))
                print("reaction designation = " + str(rates_names[x]) + " creation of species")
                diff_input[species[y][0]]["creation"][rates_names[x]] = species_lhs

        # else:
            # print(str(species[y][0]) + " not found in reaction")
        print(diff_input)
        a = input("press return to continue")
with open('diff_input.txt', 'w') as file:
    file.write(str(diff_input))

return diff_input

часть сохранения файла является необязательной, кто-нибудь еще сталкивался со словарем, заменяющим существующие ключи новыми ключами?

Спасибо за ваше терпение, и я ценю любые советы по моему форматированию (я пытался сделать его как можно лучше, не включая остальную часть сценария)

1 Ответ

0 голосов
/ 15 января 2019

Фактическое значение вашего species[1][0] должно быть равным species[0][0], поэтому, когда оно переходит ко второму значению x, присваивание diff_input[species[y][0]] = {} перезапишет поддикт к предыдущему итерация, поскольку species[y][0] остается неизменным.

Проще говоря, используя пример кода, во внешнем цикле вы выполняете следующую инициализацию:

A["Q"] = {}
A["Q"]["creation"] = {}

так что даже если ваш внутренний цикл присваивает некоторые значения поддикте:

A["Q"]["creation"]["reactants_1"] = ["R1","R2"]

A["Q"] = {} перезапишет его на следующей итерации, пока "Q" остается основным ключом для назначения.

...