Python Forum
update dict as per range of values
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
update dict as per range of values
#1
I am parsing, ZyXEL DSLAM configuration file, support required to dict as per range of data.

from ciscoconfparse import CiscoConfParse
from ciscoconfparse.ccp_util import IPv4Obj
conf_file = "f:/10.217.129.53_2019-07-19.dat"
confparse = CiscoConfParse(conf_file)
adsl_names = confparse.find_blocks(r"^adsl name ")


data = []

for name in adsl_names:
    adsl_details = {}
    adsl_port = name.strip()[len("adsl name "):].split(' ')[0]
    customer_name = name.strip()[len("adsl name "):][2:]
    adsl_details['port'] = adsl_port
    adsl_details['customer'] = customer_name
    data.append(adsl_details)
    """processing conf line like 'adsl name 3,24 reliance park
       would like to store data like
       port:3 customer:reliance park
       port:24 customer:reliance park"""
    if ',' in name:
        start_port = name.strip()[len("adsl name "):].split(' ')[0].split(',')[0]
        end_port = name.strip()[len("adsl name "):].split(' ')[0].split(',')[0]
        customer_name = name.strip()[len("adsl name "):].split(' ')[1:]
        #appending first port and customer value
        adsl_details['port'] = start_port
        adsl_details['customer'] = customer_name
        data.append(adsl_details)
        #appending second port and customer value
        adsl_details['port'] = end_port
        adsl_details['customer'] = customer_name
        data.append(adsl_details)
        
    """processing conf like like 'adsl name 11~16,20~21 shivraj patil'
       where I want to process and store data like
       port:11 customer:shivraj patil
       port:12 customer:shivraj patil
       port:13 customer:shivraj patil
       port:14 customer:shivraj patil
       port:15 customer:shivraj patil
       port:16 customer:shivraj patil
       port:20 customer:shivraj patil
       port:21 customer:shivraj patil"""
             
       
    if '~' in name and name.count('~') == 2:
        first_range = name.strip()[len("adsl name "):].split(',')[0]
        first_range_start = name.strip()[len("adsl name "):].split(',')[0].split('~')[0]
        first_range_end = name.strip()[len("adsl name "):].split(',')[0].split('~')[1]
        customer_name = name.strip()[len("adsl name "):].split(',')[1].split(' ')[1:]
        customer_name_fist_range = ' '.join(customer_name)
        
        for port in range(int(first_range_start),int(first_range_end)+1):
            #print(port)
            adsl_details['port'] = port
            adsl_details['customer'] = customer_name_fist_range
            data.append(adsl_details)
        second_range = name.strip()[len("adsl name "):].split(',')[1].split(' ')[0]
        customer_name = name.strip()[len("adsl name "):].split(',')[1].split(' ')[1:]
        #print(second_range)
        second_range_start = second_range.split('~')[0]
        second_range_end = second_range.split('~')[1]
        #print(second_range_start,second_range_end)
        for second_range_port in range(int(second_range_start),int(second_range_end)+1):
            #print(second_range_port)
            adsl_details['port'] = second_range_port
            adsl_details['customer'] = customer_name
            data.append(adsl_details)
        
for items in data:
    print(items)
Output:
{'port': '1', 'customer': 'Ashank Race PVT LTD'} {'port': '2', 'customer': 'praful'} {'port': '3', 'customer': ['reliance', 'park']} {'port': '3', 'customer': ['reliance', 'park']} {'port': '3', 'customer': ['reliance', 'park']} {'port': '5', 'customer': 'sort & ltd'} {'port': '7', 'customer': 'kishor'} {'port': '8', 'customer': 'syed'} {'port': '9', 'customer': 'pinki'} {'port': '10', 'customer': ' Sushil'} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': 21, 'customer': ['shivraj', 'patil']} {'port': '17', 'customer': ' urvi'} {'port': '22', 'customer': ' Ritesh Patil'} {'port': '23', 'customer': ' kankunta'} {'port': '25', 'customer': ' abh=hek'} {'port': '27', 'customer': ' Tanuja'} {'port': '29', 'customer': ' Kamal'} {'port': '32', 'customer': ' M/S Balaji'} {'port': '33', 'customer': ' M/s Balaji'} {'port': '37', 'customer': ' freeg wifi'} {'port': '38', 'customer': ' anjana'}
Reply
#2
What's your question?
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
I am not able to print like this

port range is
11~16,20~21

Quote:{'port': 11, 'customer': ['shivraj', 'patil']}
{'port': 12, 'customer': ['shivraj', 'patil']}
{'port': 13, 'customer': ['shivraj', 'patil']}
{'port': 14, 'customer': ['shivraj', 'patil']}
{'port': 15, 'customer': ['shivraj', 'patil']}
{'port': 16, 'customer': ['shivraj', 'patil']}
{'port': 20, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}

where as its printing
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}
{'port': 21, 'customer': ['shivraj', 'patil']}

conf file block as below

Quote:adsl name 1 Ashank Race PVT LTD
adsl name 2 praful
adsl name 3,24 reliance park
adsl name 5 sort & ltd
adsl name 7 kishor
adsl name 8 syed
adsl name 9 pinki
adsl name 10 Sushil
adsl name 11~16,20~21 shivraj patil
adsl name 17 urvi
adsl name 22 Ritesh Patil
adsl name 23 kankunta
adsl name 25 abh=hek
adsl name 27 Tanuja
adsl name 29 Kamal
adsl name 32 M/S Balaji
adsl name 33 M/s Balaji
adsl name 37 freeg wifi
adsl name 38 anjana
Reply
#4
Hi All,

I am able to print desired output line by line, however I am storing output in Dict and later appending to List.

My issue is, not able to print dict correctly, something is going wrong.

data = """adsl name 1 Ashank Race PVT LTD
adsl name 2 praful
adsl name 3,55 reliance park
adsl name 5 sort & ltd
adsl name 7 kishor
adsl name 8 syed
adsl name 9 pinki
adsl name 10 Sushil
adsl name 11~16,20~21 shivraj patil
adsl name 17 urvi
adsl name 22 Ritesh Patil
adsl name 23 kankunta
adsl name 25 abh=hek
adsl name 27 Tanuja
adsl name 29 Kamal
adsl name 32 M/S Balaji
adsl name 33 M/s Balaji
adsl name 37 freeg wifi
adsl name 38 anjana"""
port_list = []

for line in data.split('\n'):
    
    port_details= {}
    if ',' in line and '~' not in line:
        #port_details = {}
       # port_range = line.strip()[len("adsl name "):]
       # customer = line.strip()[len("adsl name "):].split(' ')[1:]
       # customer = ' '.join(customer)
       # first_port = port_range.split(',')[0]
       # second_port = port_range.split(',')[1].split(' ')[0]
       # port_details_1['port'] = first_port
       # port_details_1['customer'] = customer
       # port_list.append(port_details_1)
        #port_details['port'] = second_port
        #port_details['customer'] = customer
        #port_list.append(port_details)
        print(first_port,customer)
        print(second_port,customer)
    if ',' and '~' in line and line.count('~') == 2:
        first_range = line.strip()[len("adsl name "):].split(' ')[0].split(',')[0]
        second_range = line.strip()[len("adsl name "):].split(' ')[0].split(',')[1]
        customer = line.strip()[len("adsl name "):].split(' ')[1:]
        customer = ' '.join(customer)
        first_range_start = first_range.split('~')[0]
        first_range_end = first_range.split('~')[1]
        second_range_start = second_range.split('~')[0]
        second_range_end = second_range.split('~')[1]
        for first_range_port in range(int(first_range_start), int(first_range_end)+1):
            port_details['port'] = first_range_port
            port_details['customer'] = customer
            print(first_range_port, customer)
            port_list.append(port_details)
            
        for second_range_port in range(int(second_range_start), int(second_range_end)+1):
            print(second_range_port, customer)
            port_details_2['port'] = second_range_port
            port_details_2['customer'] = customer
            port_list.append(port_details_2)
    if '~' in line and (line.count('~')) == 1:
        range_start = line.strip()[len("adsl name "):].split(' ')[0].split('~')[0]
        range_end = line.strip()[len("adsl name "):].split(' ')[0].split('~')[1]
        customer = line.strip()[len("adsl name "):].split(' ')[1:]
        customer = ' '.join(customer)
        for range_port in range(int(range_start), int(range_end)+1):
            print(range_port, customer)
            port_details['port'] = range_port
            port_details['customer'] = customer
            port_list.append(port_details)
    else:
        if ',' not in line:
            port = line.strip()[len("adsl name "):].split(' ')[0]
            customer = line.strip()[len("adsl name "):].split(' ')[1:]
            customer = ' '.join(customer)
            print(port, customer)
            port_details['port'] = port
            port_details['customer'] = customer
            port_list.append(port_details)
for details in port_list:
    print(details['port'],details['customer'])


Line by Line output
Output:
1 Ashank Race PVT LTD 2 praful 3 praful 24 praful 5 sort & ltd 7 kishor 8 syed 9 pinki 10 Sushil 11 shivraj patil 12 shivraj patil 13 shivraj patil 14 shivraj patil 15 shivraj patil 16 shivraj patil 20 shivraj patil 21 shivraj patil 17 urvi 22 Ritesh Patil 23 kankunta 25 abh=hek 27 Tanuja 29 Kamal 32 M/S Balaji 33 M/s Balaji 37 freeg wifi 38 anjana
Dict output
Output:
1 Ashank Race PVT LTD 2 praful 5 sort & ltd 7 kishor 8 syed 9 pinki 10 Sushil 16 shivraj patil 16 shivraj patil 16 shivraj patil 16 shivraj patil 16 shivraj patil 16 shivraj patil 21 shivraj patil 21 shivraj patil 17 urvi 22 Ritesh Patil 23 kankunta 25 abh=hek 27 Tanuja 29 Kamal 32 M/S Balaji 33 M/s Balaji 37 freeg wifi 38 anjana
difference

Output:
11 shivraj patil 12 shivraj patil 13 shivraj patil 14 shivraj patil 15 shivraj patil 16 shivraj patil 20 shivraj patil 21 shivraj patil =-=-=-=-=-== 16 shivraj patil 16 shivraj patil 16 shivraj patil 16 shivraj patil 16 shivraj patil 16 shivraj patil 21 shivraj patil 21 shivraj patil
Reply
#5
You need to move the definition of dict post_details to inner loop. You always update the same dict during the loop, so the elements are same.
port_details = {} # not here
for first_range_port in range(int(first_range_start), int(first_range_end)+1):
    port_details = {} # put it here
    port_details['port'] = first_range_port
    port_details['customer'] = customer
    print(first_range_port, customer)
    port_list.append(port_details)
Reply
#6
observed same issue, after dict in loop

now some improvement, however some difference

data = """adsl name 1 Ashank Race PVT LTD
adsl name 2 praful
adsl name 3,55 reliance park
adsl name 5 sort & ltd
adsl name 7 kishor
adsl name 8 syed
adsl name 9 pinki
adsl name 10 Sushil
adsl name 11~16,20~21 shivraj patil
adsl name 17 urvi
adsl name 22 Ritesh Patil
adsl name 23 kankunta
adsl name 25 abh=hek
adsl name 27 Tanuja
adsl name 29 Kamal
adsl name 32 M/S Balaji
adsl name 33 M/s Balaji
adsl name 37 freeg wifi
adsl name 38 anjana"""
port_list = []

for line in data.split('\n'):
    port_details= {}
    if ',' in line and '~' not in line:
        print(first_port,customer)
        print(second_port,customer)
    if ',' and '~' in line and line.count('~') == 2:
        first_range = line.strip()[len("adsl name "):].split(' ')[0].split(',')[0]
        second_range = line.strip()[len("adsl name "):].split(' ')[0].split(',')[1]
        customer = line.strip()[len("adsl name "):].split(' ')[1:]
        customer = ' '.join(customer)
        first_range_start = first_range.split('~')[0]
        first_range_end = first_range.split('~')[1]
        second_range_start = second_range.split('~')[0]
        second_range_end = second_range.split('~')[1]
        for first_range_port in range(int(first_range_start), int(first_range_end)+1):
            port_details = {} 
            port_details['port'] = first_range_port
            port_details['customer'] = customer
            print(first_range_port, customer)
            port_list.append(port_details)
            
        for second_range_port in range(int(second_range_start), int(second_range_end)+1):
            print(second_range_port, customer)
            port_details_2['port'] = second_range_port
            port_details_2['customer'] = customer
            port_list.append(port_details_2)
    if '~' in line and (line.count('~')) == 1:
        range_start = line.strip()[len("adsl name "):].split(' ')[0].split('~')[0]
        range_end = line.strip()[len("adsl name "):].split(' ')[0].split('~')[1]
        customer = line.strip()[len("adsl name "):].split(' ')[1:]
        customer = ' '.join(customer)
        for range_port in range(int(range_start), int(range_end)+1):
            #port_details = {}
            print(range_port, customer)
            port_details['port'] = range_port
            port_details['customer'] = customer
            port_list.append(port_details)
    else:
        if ',' not in line:
            port = line.strip()[len("adsl name "):].split(' ')[0]
            customer = line.strip()[len("adsl name "):].split(' ')[1:]
            customer = ' '.join(customer)
            print(port, customer)
            port_details['port'] = port
            port_details['customer'] = customer
            port_list.append(port_details)
print('Printing Dict ----------- ')
for details in port_list:
    
    print(details['port'],details['customer'])
Output:
1 Ashank Race PVT LTD 2 praful 3 praful 24 praful 5 sort & ltd 7 kishor 8 syed 9 pinki 10 Sushil 11 shivraj patil 12 shivraj patil 13 shivraj patil 14 shivraj patil 15 shivraj patil 16 shivraj patil 20 shivraj patil 21 shivraj patil 17 urvi 22 Ritesh Patil 23 kankunta 25 abh=hek 27 Tanuja 29 Kamal 32 M/S Balaji 33 M/s Balaji 37 freeg wifi 38 anjana Printing Dict ----------- 1 Ashank Race PVT LTD 2 praful 5 sort & ltd 7 kishor 8 syed 9 pinki 10 Sushil 11 shivraj patil 12 shivraj patil 13 shivraj patil 14 shivraj patil 15 shivraj patil 16 shivraj patil 21 shivraj patil 21 shivraj patil 17 urvi 22 Ritesh Patil 23 kankunta 25 abh=hek 27 Tanuja 29 Kamal 32 M/S Balaji 33 M/s Balaji 37 freeg wifi 38 anjana
Reply
#7
Here a different approach. Before you must do a transformation, that all ports are in a list.

unsorted_ports = [item['port'] for item in data]
def find_port_ranges(ports):
    # the set returns only unique elements
    # then the set is sorted in reversed order
    # the resulting object is a sorted list
    ports = sorted(set(ports), reverse=True)
    # pop the last element from list, which is the smallest
    start = last = ports.pop()
    # start indicates the start range
    # last is always the value from previous iteration
    # repeat until the list ports is empty
    while ports:
        # pop the last element from list
        value = ports.pop()
        if value - 1 != last:
            yield (start, last)
            start = last = value
        else:
            # last value is current value - 1
            last = value
    # yield the last elements
    yield (start, value)
Test:
Output:
>>> example_ports = [1,2,4,3,20,10,11,13,12,21,23,28,22,25,26,29,100,101,103] >>> list(find_port_ranges(example_ports)) [(1, 4), (10, 13), (20, 23), (25, 26), (28, 29), (100, 101), (103, 103)]
A second function can do the formatting:

def format_port_ranges(ports):
    ranges = []
    for start, end in find_port_ranges(ports):
        if start != end:
            ranges.append(f'{start}-{end}')
        else:
            ranges.append(str(start))
    return 'Ports: ' + ', '.join(ranges) # split ranges by comma
Output:
>>> format_port_ranges([1,2,3,4,10,20,11,12,13,21,22,23,22,25,26,29]) 'Ports: 1-4, 10-13, 20-23, 25-26, 29'
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#8
Thanks DeaD_EyE, still figure out how to implement this.

Thanks DeaD_EyE, still not able to figure out how to implement this.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  dict class override: how access parent values? Andrey 1 1,594 Mar-06-2022, 10:49 PM
Last Post: deanhystad
  matplotlib x axis range goes over the set range Pedroski55 5 3,111 Nov-21-2021, 08:40 AM
Last Post: paul18fr
  Removing nan values from a dict tomtom 8 6,868 Oct-05-2021, 06:44 PM
Last Post: tomtom
  How can I count values between range dates ? Eidrizi 2 2,412 Mar-17-2021, 01:26 PM
Last Post: Eidrizi
  How to update values in a pyarrow table? xraphael75 1 3,625 Jan-25-2021, 02:14 PM
Last Post: xraphael75
Question Python + Google Sheet | Best way to update specific cells in a single Update()? Vokofe 1 2,627 Dec-16-2020, 05:26 AM
Last Post: Vokofe
  Looking for help in Parse multiple XMLs and update key node values and generate Out.. rajesh3383 0 1,847 Sep-15-2020, 01:42 PM
Last Post: rajesh3383
  Trouble with converting list , dict to int values! faryad13 7 3,671 Sep-04-2020, 06:25 AM
Last Post: faryad13
  Sort a dict in dict cherry_cherry 4 62,581 Apr-08-2020, 12:25 PM
Last Post: perfringo
  How to access specific values from a dict? t4keheart 6 3,034 Feb-05-2020, 11:34 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020