我有一个包含少数数据中心IP地址列表的.csv文件。该列表目前看起来类似于下表:
Data_Center_Name IP
DC_1 52.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
我想将列表转换为单独的列表,例如:
DC_1 = [52.102.182.1-52.102.182.5,
27.101.178.15-27.101.178.17,
23.201.165.7]
DC_2 = [55.200.162.10-55.200.162.13]
DC_3 = [30.101.102.4]
任何人都可以帮我使用python吗?
答案 0 :(得分:2)
*此答案已被编辑,导致不小心阅读问题*
单list
范围
df[['P1','P2']]=df.IP.str.rsplit('.',1).apply(pd.Series)
d=df.sort_values(['Data_Center_Name','P1','P2']).\
groupby(['Data_Center_Name','P1']).\
IP.apply(lambda x : x.iloc[0]+'-'+x.iloc[-1] if len(x)>1 else x.iloc[0] )
d
Out[388]:
Data_Center_Name P1
DC_1 23.201.165 23.201.165.7
27.101.178 27.101.178.15-27.101.178.17
50.102.182 50.102.182.2
52.102.182 52.102.182.1-52.102.182.5
DC_2 55.200.162 55.200.162.10-55.200.162.13
DC_3 30.101.102 30.101.102.4
Name: IP, dtype: object
为了获得结果
d.groupby(level=0).apply(list)
Out[392]:
Data_Center_Name
DC_1 [23.201.165.7, 27.101.178.15-27.101.178.17, 50...
DC_2 [55.200.162.10-55.200.162.13]
DC_3 [30.101.102.4]
Name: IP, dtype: object
答案 1 :(得分:2)
我的解决方案是:
将每个IP转换为十进制数
排序并从列表编号中获取范围(间隔)
将它们转换为IP格式。
<强>输入:强>
var s3Client = s3.getClient(config.region)
第1步:
IP =&gt;二进制=&gt;小数
ips = [ "52.102.182.2", "52.102.182.4", "52.102.182.1", "52.102.182.5", "52.102.182.3",
"27.101.178.17", "27.101.178.16", "27.101.178.15",
"23.201.165.7", ]
或IP =&gt;小数
# Convert ips to binary strings
bins = [''.join([bin(int(i))[2:].zfill(8) for i in ip.split('.')]) for ip in ips]
# Convert binary strings to decimal numbers
numbers = [int(b, 2) for b in bins]
第2步:
# Convert ips to decimal numbers
numbers = [sum((256 ** (3 - k)) * int(n) for k, n in enumerate(ip.split('.'))) for ip in ips]
第3步:
# Sort decimal numbers
numbers.sort()
# Get ranges from decimal numbers
ranges = []
tmp = []
for i in range(len(numbers)):
tmp.append(numbers[i])
if (i == len(numbers) - 1) or (numbers[i + 1] > numbers[i] + 1):
if len(tmp) == 1:
ranges.append(tmp[0])
else:
ranges.append((tmp[0], tmp[-1]))
tmp = []
<强>输出:强>
# Convert dec ranges to ip ranges
def dec_to_ip(n):
return '.'.join([str(int(n % 256 ** (4 - k) / 256 ** (3 - k))) for k in range(4)])
# Final result
ip_ranges = [(dec_to_ip(r[0]), dec_to_ip(r[1])) if type(r) == tuple else dec_to_ip(r) for r in ranges]
答案 2 :(得分:1)
使用python3(如果需要,我可以使用python2)
利用ipaddress
和groupby
内置库以及其他内置程序:
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
StringIO
来模拟从文件中读取):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()}
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']}
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()}
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']}
有效吗!谢谢。可以获得输出:{'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']} -
是的,请更改此行:
groups.append("{}-{}".format(group[0], str(group[-1]).split('.')[-1]))
对此:
groups.append("{}-{}".format(group[0], group[-1]))