Using python3 (I can use python2 if required)
Using the ipaddress and groupby built-in libraries and other built-in goodies:
Create a function that converts a list of ipaddress objects to ranges:
def create_range(ip_addresses): groups=[] for _, g in itertools.groupby(enumerate(sorted(ip_addresses)), lambda (i,x):i-int(x)): group = map(operator.itemgetter(1), g) if len(group) > 1: groups.append("{}-{}".format(group[0], str(group[-1]).split('.')[-1])) else: groups.append(str(group[0])) return groups
import the necessary libraries, analyze values ββfrom csv (using StringIO to simulate reading from a file):
import csv ## for reading csv file import ipaddress ## for creating ip address objects import io ## for mimicking reading csv file import operator ## for grouping operation import itertools ## for grouping operation import collections ## for creating a defaultdict ips = defaultdict(list) csv_file = u"""Data_Center_Name, IP DC_1, 50.102.182.2 DC_1, 52.102.182.4 DC_1, 52.102.182.1 DC_1, 52.102.182.5 DC_1, 52.102.182.3 DC_1, 27.101.178.17 DC_1, 27.101.178.16 DC_1, 27.101.178.15 DC_1, 23.201.165.7 DC_2, 55.200.162.10 DC_2, 55.200.162.12 DC_2, 55.200.162.13 DC_2, 55.200.162.11 DC_3, 30.101.102.4 """ with io.StringIO(csv_file) as f: reader = list(csv.reader(f)) for (dc, ip) in reader[1:]: ip = ipaddress.IPv4Address(unicode(ip.strip())) ips[dc.strip()].append(ip) result = {dc: create_range(ip_range) for dc, ip_range in ips.items()}
Result:
In [92]: result Out[92]: {'DC_1': ['23.201.165.7', '27.101.178.15-17', '50.102.182.2', '52.102.182.1', '52.102.182.3-5'], 'DC_2': ['55.200.162.10-13'], 'DC_3': ['30.101.102.4']}
python2
import csv ## for reading csv file import ipaddress ## for creating ip address objects from StringIO import StringIO ## for mimicking reading csv file import operator ## for grouping operation import itertools ## for grouping operation import collections ## for creating a defaultdict def create_range(ip_addresses): groups=[] for _, g in itertools.groupby(enumerate(sorted(ip_addresses)), lambda (i,x):i-int(x)): group = map(operator.itemgetter(1), g) if len(group) > 1: groups.append("{}-{}".format(group[0], str(group[-1]).split('.')[-1])) else: groups.append(str(group[0])) return groups ips = collections.defaultdict(list) csv_file = """Data_Center_Name, IP DC_1, 50.102.182.2 DC_1, 52.102.182.4 DC_1, 52.102.182.1 DC_1, 52.102.182.5 DC_1, 52.102.182.3 DC_1, 27.101.178.17 DC_1, 27.101.178.16 DC_1, 27.101.178.15 DC_1, 23.201.165.7 DC_2, 55.200.162.10 DC_2, 55.200.162.12 DC_2, 55.200.162.13 DC_2, 55.200.162.11 DC_3, 30.101.102.4 """ reader = csv.reader(StringIO(csv_file)) next(reader) for (dc, ip) in reader: ip = ipaddress.IPv4Address(unicode(ip.strip())) ips[dc.strip()].append(ip) result = {dc: create_range(ip_range) for dc, ip_range in ips.items()}
result with py2 code
print result {'DC_2': ['55.200.162.10-13'], 'DC_3': ['30.101.102.4'], 'DC_1': ['23.201.165.7', '27.101.178.15-17', '50.102.182.2', '52.102.182.1', '52.102.182.3-5']}
Works! Thank you You can get the output: {'DC_2': ['55 .200.162.10-55.200.162.13 '],' DC_3 ': ['30 .101.102.4'], 'DC_1': ['23 .201.165.7 ', '27 .101.178.15-27.101 .178.17 ', '50 .102.182.2', '52 .102.182.1 ', '52 .102.182.3-52.102.182.5']} -
Yes, change this line:
groups.append("{}-{}".format(group[0], str(group[-1]).split('.')[-1]))
For this:
groups.append("{}-{}".format(group[0], group[-1]))