Search code examples
pythontelnetlib

How to create a list dict dynamically with Python


I have this input to handle:

['', '', '', '', '  Huawei Integrated Access Software (MA5600T).', '  Copyright(C) Huawei Technologies Co., Ltd. 2002-2014. All rights reserved.', '', '  -----------------------------------------------------------------------------', '  User last login information:', '  -----------------------------------------------------------------------------', '  Access Type : Telnet ', '  IP-Address  : 1.1.1.1', '  Login  Time : 2020-12-24 11:51:33+01:00', '  Logout Time : 2020-12-24 11:51:38+01:00', '  -----------------------------------------------------------------------------', '', 'OLT-SALUZZO_01>enable', '', 'OLT-SALUZZO_01#display ont autofind all \x1b[1D\x1b[1C', '   ----------------------------------------------------------------------------', '   Number              : 1', '   F/S/P               : 0/17/7', '   Ont SN              : 485754437D85CA9E (HWTC-7D85CA9E)', '   Password            : 0x00000000000000000000', '   Loid                : ', '   Checkcode           : ', '   VendorID            : HWTC', '   Ont Version         : 159D.A', '   Ont SoftwareVersion : V5R019C00S100', '   Ont EquipmentID     : EG8145V5', '   Ont autofind time   : 2020-12-24 08:38:28+01:00', '   ----------------------------------------------------------------------------', '   Number              : 2', '   F/S/P               : 0/17/7', '   Ont SN              : 48575443A9517A9E (HWTC-A9517A9E)', '   Password            : 0x00000000000000000000', '   Loid                : ', '   Checkcode           : ', '   VendorID            : HWTC', '   Ont Version         : 159D.A', '   Ont SoftwareVersion : V5R019C00S100', '   Ont EquipmentID     : EG8145V5', "---- More ( Press 'Q' to break ) ----"]

and I need to create from this an output like this:

[{'F/S/P': '0/17/7', 'SN': ' 485754437D85CA9E', 'Password': None}, {'F/S/P': '0/17/7', 'SN': '48575443A9517A9E ', 'Password': None}]

My function is something like that:

tn.write("display ont autofind all ".encode('utf-8') + b"\n")
return_lineid = tn.read_until('The number of GPON'.encode('utf-8'), 3).decode('utf-8')
data_return = return_lineid.splitlines()
autofind_list=[]
records = []
current_record = {}
for line in data_return:
    line = line.strip()
    if not line:  # empty line
        records.append(current_record)
        current_record = {}
    else:
        if "F/S/P" in line:
            key, value = line.split(':')
            key = key.strip()
            value = value.strip()
            current_record[key] = value
            print(current_record)
        if "Ont SN" in line:
            key, value = line.split(':')
            key = key.strip()
            value = value.strip()
            value = re.sub(r'\(.*\)', '', value)
            current_record[key] = value
            print(current_record)
        if "Password" in line:
            key, value = line.split(':')
            key = key.strip()
            value = value.strip()
            if value == '0x00000000000000000000':
                current_record[key]=None
            else:
                current_record[key] = value

        autofind_list.append(current_record.copy())

#for removing same records
seen = set()
new_l = []
for d in autofind_list:
    t = tuple(d.items())
    if t not in seen:
        seen.add(t)
        new_l.append(d)

print(new_l)

But it returns this, I've almost reached my goal:

[{}, {'F/S/P': '0/17/7'}, {'F/S/P': '0/17/7', 'Ont SN': '485754437D85CA9E '}, {'F/S/P': '0/17/7', 'Ont SN': '485754437D85CA9E ', 'Password': None}, {'F/S/P': '0/17/7', 'Ont SN': '48575443A9517A9E ', 'Password': None}]

But I would like to remove useless object like {}, {'F/S/P': '0/17/7'}

Someone could kindly help me with this problem? or could give me an hint?

Thank you in advance


Solution

  • I am not sure what your plan was with this autofind_list, but I assume it was your attempt at solving the problem that one record doesn't appear in records. This can be solved by simply adding the current_record after the loop is finished.

    Then the only problem is the first empty record, happening because at the beginning there is an unnecessary empty line. This can be done by simply checking if current_record is filled before adding it to records (this also prevents problems if two empty lines are in a row).

    Here is the full code:

    records = []
    current_record = {}
    for line in data_return:
        line = line.strip()
        if not line:  # empty line
            if current_record: # no data recorded
                records.append(current_record)
                current_record = {}
        else:
            if "F/S/P" in line:
                key, value = line.split(':')
                key = key.strip()
                value = value.strip()
                current_record[key] = value
            if "Ont SN" in line:
                key, value = line.split(':')
                key = key.strip()
                value = value.strip()
                value = re.sub(r'\(.*\)', '', value)
                current_record[key] = value
            if "Password" in line:
                key, value = line.split(':')
                key = key.strip()
                value = value.strip()
                if value == '0x00000000000000000000':
                    current_record[key] = None
                else:
                    current_record[key] = value
    
    if current_record:
        records.append(current_record)
    

    records now includes the list I think you want.


    Since your example data in the post doesn't actually represent the input you are given, in which records are separated by ---- dash-only lines, you need to replace if not line: with if not line or set(line) == {'-'}:.