Python Forum
Lists - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Lists (/thread-40874.html)



Lists - blake7 - Oct-06-2023

Fairly new to Python, having some issues with lists.

I am trying to scrape a Cisco Switch config file

So I am splitting the file using ! and the entries are then appending to an empty list.

This bit seems to work ok, I can see the 196 list entries that it creates.

I am then trying to copy the list to another list to work on it, removing any entry that doesn't contain the string 'GigabitEthernet'

It is doing something as the new list is only 98 entries long, but when I look at it, it seems to have removed every even entry in the list.

config list:
[(0, 'Current configuration : 33940 bytes\n'), (1, '\n'), (2, ' Last configuration change at 07:09:55 zone Thu May 5 2022 by \n'), (3, ' NVRAM config last updated at 07:10:13 zone Thu May 5 2022 by \n'), ...

working_config:
[(1, '\n'), (3, ' NVRAM config last updated at 07:10:13 zone Thu May 5 2022 by y\n'), ...


Any Ideas ? I'm obviously doing something wrong, just cant see what it is.


# declare an empty list

config = []


# open the file

with open(r"c:\\Temp\python\switch\switch.txt", mode='r') as f:
    switchports = f.read().split('!')
    
for row in enumerate(switchports):
    config.append(row)


# create a copy of the list

working_config = list(config)
print(working_config)

for x in working_config:
    if "GigabitEthernet" not in x:
        working_config.remove(x)



RE: Lists - buran - Oct-06-2023

Don't modify list while iterating over it.

How to remove items from a list while iterating?


In your case you can construct working_config directly with list comprehension, while iterating over config. i.e. no need to create copy and then remove elements from it
working_config = [item for item in config if "GigabitEthernet" in item]
Note, there is one more problem - because row is a tuple (due to using enumerate) where first element is row index, and the second element - string resulting from splitting lines in the file, I would expect no elements will be removed.

Could you provide sample config file in full (i.e. not full content but how it looks unmodified)
Finally, you may want to have on third-party package like https://pypi.org/project/ciscoconfparse/


RE: Lists - blake7 - Oct-06-2023

Hi Buran,

thanks for the prompt reply. I had tried something like that before. I would need to go through the config file and redact a lot of information, before I could post it.


If I print the len of config I can see 196

If I print config index 111 for example I can see an entry for 'GigabitEthernet'

However as you said when I iterate over config it returns a length of 0 and the list is empty.


196

(111, '\ninterface GigabitEthernet1/0/2\n description VM Trunk\n switchport trunk encapsulation dot1q\n switchport trunk allowed vlan 97,163\n switchport mode trunk\n switchport nonegotiate\n speed 1000\n duplex full\n no cdp enable\n')
0
[]


RE: Lists - blake7 - Oct-06-2023

This seems to work a bit better:

# declare an empty list

config = []


# open the file

with open(r"c:\\Temp\python\switch\switch.txt", mode='r') as f:
 #   switchports = f.read().split('!')
    
     for switchports in f.read().split('!'):
        config.append(switchports)


# create a copy of the list

working_config = [item for item in config if "GigabitEthernet" in item]
Now I get 196 for the len of config

and 31 for the len of working_config

I can see information in the working_config list, but it looks like all the indexes contain the same information


RE: Lists - buran - Oct-06-2023

working_config = [(idx, item) for idx, item in config if "GigabitEthernet" in item]
That is if you really do need to keep the row index.
Why do you need them? I would remove the enumerate() if you don't need the index
yeah, that was whay I mean, if you don't need the index


RE: Lists - buran - Oct-06-2023

sample.cfg attached

with open('sample.txt') as f:
    cnfg = f.read().split('!')

working_cnfg = [item for item in cnfg if 'FastEthernet' in item]

for item in working_cnfg:
    print(item)



RE: Lists - buran - Oct-06-2023

Using ciscoconfparser package mentioned above

from ciscoconfparse import CiscoConfParse

confparse = CiscoConfParse('sample.txt')
interface_cmds = confparse.find_objects("FastEthernet")
for interface_cmd in interface_cmds:
    print('\n'.join(interface_cmd.ioscfg))
Output:
interface FastEthernet0 no ip address interface FastEthernet1 no ip address interface FastEthernet2 no ip address interface FastEthernet3 switchport mode trunk no ip address interface FastEthernet4 ip address 192.168.12.2 255.255.255.0 no ip directed-broadcast (default) speed auto ip nat outside ip access-group 103 in no cdp enable crypto ipsec client ezvpn ezvpnclient outside crypto map static-map
this looks useful
https://github.com/hoelsner/python-script-examples