重新排列 Python 中的元素
Rearranging elements in Python
我是 Python 的新手,我无法获得 this.I 有一个列表,我想从那里获取输入并将其写入文件。
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
我正在尝试什么:
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
i = 0
while i < len(p):
start = p[i].split('/')
if (start[0] == 'Eth101'):
i += 3
key = start[0]
i += 1
while i < len(p) and p[i].split('/')[0] == key:
i += 1
end = p[i-1].split('/')
fw2.write('confi ' + start[0] + '/' + start[1] + '-' + end[1] + '\n mode\n')
我在找什么:
abc1.txt 应该有
int Eth1/1
mode
int Eth1/5
mode
int Eth2/1
mode
int Eth 2/4
mode
abc2.txt 应该有:
int Eth101/1/1-3
mode
int Eth102/1/1-3
mode
int Eth103/1/1-4
mode
int Eth104/1/1-4
mode
So any Eth having 1 digit before " / " ( e:g Eth1/1 or Eth2/2
)should be in one file that is abc1.txt .
Any Eth having 3 digit before " / " ( e:g Eth101/1/1 or Eth 102/1/1
) should be in another file that is abc2.txt and .As these are in
ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc
有什么想法吗?
我认为您在这里根本不需要正则表达式。您的所有项目都以 'Eth' 开头,后跟一位或多位数字。因此,您可以在第一个 /
发生之前检查项目的长度,然后将其写入文件。
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')
我稍微重构了您的代码以使 with
-语句发挥作用。这将在最后正确处理关闭文件。也没有必要在序列上迭代两次,所以一次迭代就完成了。
如果数据不如提供的那么干净,那么您可能需要使用正则表达式。独立于正则表达式本身,通过编写 if re.match(r'((Eth\d{1}\/\d{1,2})', "p" )
可以证明是否可以为字符串 "p"
上的给定正则表达式创建匹配对象,而不是变量 p
的值。这是因为您在 p
周围使用了 "
。
所以这应该适用于您的示例。如果你真的需要一个正则表达式,这将解决你的问题,找到一个好的正则表达式来满足你的需求而没有任何其他问题。
As these are in ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc
这可以通过先计算字符串然后将其写入文件来实现。但这更像是一个单独的问题。
更新
计算正确的网络范围并非易事。在这里,我可以向您介绍一种方法,它不会更改我的代码但会添加一些功能。这里的技巧是获取不被其数量打断的连接网络组。为此,我复制了 consecutive_groups。您当然也可以执行 pip install more-itertools
以获得该功能。而且我还将列表转换为字典以准备魔法,然后将字典重新转换为列表。肯定有更好的方法,但这至少适用于您的输入数据。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from itertools import groupby
from operator import itemgetter
p = ['Eth1/1', 'Eth1/5', 'Eth2/1', 'Eth2/4', 'Eth101/1/1', 'Eth101/1/2',
'Eth101/1/3', 'Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3', 'Eth103/1/1',
'Eth103/1/2', 'Eth103/1/3', 'Eth103/1/4', 'Eth104/1/1', 'Eth104/1/2',
'Eth104/1/3', 'Eth104/1/4']
def get_network_ranges(networks):
network_ranges = {}
result = []
for network in networks:
parts = network.rpartition("/")
network_ranges.setdefault(parts[0], []).append(int(parts[2]))
for network, ranges in network_ranges.items():
ranges.sort()
for group in consecutive_groups(ranges):
group = list(group)
if len(group) == 1:
result.append(network + "/" + str(group[0]))
else:
result.append(network + "/" + str(group[0]) + "-" +
str(group[-1]))
result.sort() # to get ordered results
return result
def consecutive_groups(iterable, ordering=lambda x: x):
"""taken from more-itertools (latest)"""
for k, g in groupby(
enumerate(iterable), key=lambda x: x[0] - ordering(x[1])
):
yield map(itemgetter(1), g)
# only one line added to do the magic
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
p = get_network_ranges(p)
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')
我是 Python 的新手,我无法获得 this.I 有一个列表,我想从那里获取输入并将其写入文件。
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
我正在尝试什么:
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
i = 0
while i < len(p):
start = p[i].split('/')
if (start[0] == 'Eth101'):
i += 3
key = start[0]
i += 1
while i < len(p) and p[i].split('/')[0] == key:
i += 1
end = p[i-1].split('/')
fw2.write('confi ' + start[0] + '/' + start[1] + '-' + end[1] + '\n mode\n')
我在找什么:
abc1.txt 应该有
int Eth1/1
mode
int Eth1/5
mode
int Eth2/1
mode
int Eth 2/4
mode
abc2.txt 应该有:
int Eth101/1/1-3
mode
int Eth102/1/1-3
mode
int Eth103/1/1-4
mode
int Eth104/1/1-4
mode
So any Eth having 1 digit before " / " ( e:g Eth1/1 or Eth2/2 )should be in one file that is abc1.txt .
Any Eth having 3 digit before " / " ( e:g Eth101/1/1 or Eth 102/1/1 ) should be in another file that is abc2.txt and .As these are in ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc
有什么想法吗?
我认为您在这里根本不需要正则表达式。您的所有项目都以 'Eth' 开头,后跟一位或多位数字。因此,您可以在第一个 /
发生之前检查项目的长度,然后将其写入文件。
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')
我稍微重构了您的代码以使 with
-语句发挥作用。这将在最后正确处理关闭文件。也没有必要在序列上迭代两次,所以一次迭代就完成了。
如果数据不如提供的那么干净,那么您可能需要使用正则表达式。独立于正则表达式本身,通过编写 if re.match(r'((Eth\d{1}\/\d{1,2})', "p" )
可以证明是否可以为字符串 "p"
上的给定正则表达式创建匹配对象,而不是变量 p
的值。这是因为您在 p
周围使用了 "
。
所以这应该适用于您的示例。如果你真的需要一个正则表达式,这将解决你的问题,找到一个好的正则表达式来满足你的需求而没有任何其他问题。
As these are in ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc
这可以通过先计算字符串然后将其写入文件来实现。但这更像是一个单独的问题。
更新
计算正确的网络范围并非易事。在这里,我可以向您介绍一种方法,它不会更改我的代码但会添加一些功能。这里的技巧是获取不被其数量打断的连接网络组。为此,我复制了 consecutive_groups。您当然也可以执行 pip install more-itertools
以获得该功能。而且我还将列表转换为字典以准备魔法,然后将字典重新转换为列表。肯定有更好的方法,但这至少适用于您的输入数据。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from itertools import groupby
from operator import itemgetter
p = ['Eth1/1', 'Eth1/5', 'Eth2/1', 'Eth2/4', 'Eth101/1/1', 'Eth101/1/2',
'Eth101/1/3', 'Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3', 'Eth103/1/1',
'Eth103/1/2', 'Eth103/1/3', 'Eth103/1/4', 'Eth104/1/1', 'Eth104/1/2',
'Eth104/1/3', 'Eth104/1/4']
def get_network_ranges(networks):
network_ranges = {}
result = []
for network in networks:
parts = network.rpartition("/")
network_ranges.setdefault(parts[0], []).append(int(parts[2]))
for network, ranges in network_ranges.items():
ranges.sort()
for group in consecutive_groups(ranges):
group = list(group)
if len(group) == 1:
result.append(network + "/" + str(group[0]))
else:
result.append(network + "/" + str(group[0]) + "-" +
str(group[-1]))
result.sort() # to get ordered results
return result
def consecutive_groups(iterable, ordering=lambda x: x):
"""taken from more-itertools (latest)"""
for k, g in groupby(
enumerate(iterable), key=lambda x: x[0] - ordering(x[1])
):
yield map(itemgetter(1), g)
# only one line added to do the magic
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
p = get_network_ranges(p)
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')