假设我有一个id列表,如:
ids= 1/1/n1..1/1/n5 , 1/1/x1 , 1/1/g1
预期产出:
1/1/n1 , 1/1/n2 , 1/1/n3 , 1/1/n4 , 1/1/n5 ,1/1/x1, 1/1/g1
意味着无论我在哪里找到' ids..ids',我都会填补空白
我写了一个非常基本的代码,但我正在寻找更多的pythonic解决方案
import re
ports_list=['1/1/n1..1/1/n8']
n = 2
port_range=[]
for port in ports_list:
if '..' in port:
groups = port.split('..') #gives ['1/1/n1', '1/1/n8']
for item in groups:
port_split = item.split('/')
port_join='/'.join(port_split[:n]), '/'.join(port_split[n:])
port_join=port_join[0]+"/"
port_split=port_split[2] # n1 n8
get_str=port_split[0][0]
num=re.findall(r'\d+', port_split) # 1 8
port_range.append(num[0])
#remove port with '..
ports_list.remove(port)
n1=port_range[0]
n2=port_range[1]
final_number_list=list(range(int(n1),int(n2)+1))
my_new_list = [ get_str + str(n) for n in final_number_list]
final_list=[ port_join + str(n) for n in my_new_list]
ports_list=ports_list+final_list
print ports_list
提供预期输出:
['1/1/n1', '1/1/n2', '1/1/n3', '1/1/n4', '1/1/n5', '1/1/n6', '1/1/n7', '1/1/n8']
但如果没有复杂的逻辑,如何轻松解决?
答案 0 :(得分:2)
不确定它比您当前的方法更具可读性或更好,但我们可以使用正则表达式从字符串中提取公共部分和范围边界:
import re
def expand(l):
result = []
pattern = re.compile(r"^(.*?)(\d+)$")
for item in l:
# determine if it is a "range" item or not
is_range = '..' in item
if not is_range:
result.append(item)
continue
# get the borders and the common reusable part
borders = [pattern.match(border).groups() for border in item.split('..')]
(common_part, start), (_, end) = borders
for x in range(int(start), int(end) + 1):
result.append("%s%d" % (common_part, x))
return result
print(expand(['1/1/n1..1/1/n8']))
print(expand(['1/1/n1..1/1/n5', '1/1/x1', '1/1/g1']))
打印:
['1/1/n1', '1/1/n2', '1/1/n3', '1/1/n4', '1/1/n5', '1/1/n6', '1/1/n7', '1/1/n8']
['1/1/n1', '1/1/n2', '1/1/n3', '1/1/n4', '1/1/n5', '1/1/x1', '1/1/g1']
^(.*?)(\d+)$
中的位置:
^
匹配字符串的开头(在我们的情况下实际上并不需要{I}} - 它会从字符串的开头开始搜索 - 只是因为“明确是优于隐含的“).match()
是一个捕获组,可以在non-greedy fashion (.*?)
是一个可以保存一个或多个连续数字的捕获组(\d+)
匹配字符串的结尾答案 1 :(得分:0)
这是基本代码;我会让你根据需要重新组合它,包括你已经拥有的列表理解。只需按照你已经做的那样划分范围。而不是解构整个字符串,只需取最后一个数字并运行范围:
ports_list=['1/1/n1..1/1/n8']
for port in ports_list:
if ".." in port:
left, right = port.split("..")
for i in range(int(left[-1]), int(right[-1])+1):
new_port = left[:-1] + str(i)
print new_port
最后一行只是为了证明正确的反应。