Python обновление словаря и добавление в конец списка с помощью цикла - PullRequest
0 голосов
/ 17 июня 2020

Есть ли правильный способ обновить словарь и добавить этот словарь в список, не вызывая дублирования. Это для использования с netmiko, и моя цель - сделать его немного динамичным c и гибким, особенно со схемой именования.

#!/usr/bin/python
import re

hosts_info = []
host = {
    'device_type': 'cisco_ios',
    'ip': 'co-acc-sw',
    'username': 'cisco',
    'password': 'notapassword',
    'secret': 'mrsecret'
}

for x in range(0, 4):
    if x < 2:
        host.update({"ip": "core-switch" + str(x)})
    elif x > 2:
        host.update({"ip": "access-switch" + str(x - 1)})
    hosts_info.append(host)
print(hosts_info)

Текущий вывод:

[{'device_type': 'cisco_ios', 'ip': 'access-switch2', 'username': 'cisco', 'password': 'notapassword', 'secret': 'mrsecret'}, 
{'device_type': 'cisco_ios', 'ip': 'access-switch2', 'username': 'cisco', 'password': 'notapassword', 'secret': 'mrsecret'}, 
{'device_type': 'cisco_ios', 'ip': 'access-switch2', 'username': 'cisco', 'password': 'notapassword', 'secret': 'mrsecret'}, 
{'device_type': 'cisco_ios', 'ip': 'access-switch2', 'username': 'cisco', 'password': 'notapassword', 'secret': 'mrsecret'}]

Я пытаюсь сделать так, чтобы он выглядел так:

[{'device_type': 'cisco_ios', 'ip': 'core-switch1', 'username': 'cisco', 'password': 'notapassword', 'secret': 'mrsecret'}, 
{'device_type': 'cisco_ios', 'ip': 'core-switch2', 'username': 'cisco', 'password': 'notapassword', 'secret': 'mrsecret'}, 
{'device_type': 'cisco_ios', 'ip': 'access-switch1', 'username': 'cisco', 'password': 'notapassword', 'secret': 'mrsecret'}, 
{'device_type': 'cisco_ios', 'ip': 'access-switch2', 'username': 'cisco', 'password': 'notapassword', 'secret': 'mrsecret'}]

Я могу заставить его работать, если я создам отдельные словари и добавлю их для разделения операторов if, просто интересно, есть ли лучший способ сделать это? спасибо.

Ответы [ 2 ]

1 голос
/ 17 июня 2020

Каждый элемент в списке должен быть собственным dict; в вашем существующем коде есть только один dict (host), который он продолжает обновлять (перезаписывая предыдущие обновления) и строит список с четырьмя ссылками на один и тот же dict.

Простой способ создать новый dict, который является частичной копией существующего dict, - это выполнить понимание словаря с помощью **olddict:

for x in range(0, 4):
    if x < 2:
        hosts_info.append({**host, "ip": "core-switch" + str(x)})
    elif x > 2:
        hosts_info.append({**host, "ip": "access-switch" + str(x - 1)})
    else:
        hosts_info.append({**host})

Это больше, чем ваш исходный код пытается выполнить (за вычетом ошибок указателя), но на самом деле не дает желаемого результата, потому что математика неверна.

Я думаю, что способ заставить математику работать будет примерно так:

hosts_info = [{
    **host, "ip": f"core-switch{x+1}" if x < 2 else f"access-switch{x-1}"
} for x in range(4)]

Или вместо того, чтобы пытаться грамотно спроектировать один l oop, который производит разные строковые значения, которые вы хотите, вычисляя смещения из разных значений int в диапазоне, вы можете просто сделать вложенный l oop где вы перебираете фактические значения, которые хотите:

hosts_info = [{
    **host, "ip": f"{switch}-switch{x}"
} for switch in ("core", "access") for x in (1, 2)]

Это гораздо более читаемый ИМО, поскольку вывод очень прямо и явно соответствует коду, тогда как сложная математика затрудняет определение того, что исходный код даже пытается произвести (и нетривиально заставить математику делать правильные вещи).

0 голосов
/ 17 июня 2020

Быстрое исправление будет следующим:

for x in range(0, 4):
    h = dict(host)
    if x < 2:
        h.update({"ip": "core-switch" + str(x + 1)})
    elif x >= 2:
        h.update({"ip": "access-switch" + str(x - 1)})
    hosts_info.append(h)

Так как вам нужно сделать явную копию вашего словаря. Однако я бы посоветовал также взглянуть на ответ Сэмвайса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...