我有一个像这样的列表
['AX95', 'BD95']
我需要将列表从AX95
扩展到BD95
,如此
['AX95', 'AY95', 'AZ95', 'BA95','BB95','BC95','BD95']
我目前的代码适用于单个字母表,例如
['A95', 'D95']
我的代码现在看起来像这样,
import re
def resolve(item):
start = int(re.search(r'\d+', item[0]).group())
end = int(re.search(r'\d+', item[1]).group())
print(item)
c = re.search(r'[a-zA-Z]+', item[0]).group()
d = re.search(r'[a-zA-Z]+', item[1]).group()
print(c, d)
for char in range(ord(c), ord(d) + 1):
yield chr(char) + str(end)
xx = resolve(['AX95', 'BD95'])
print(list(xx))
怎么做?
答案 0 :(得分:4)
您无法在多个字符上直接使用ord()
,它会因错误而错误显示 -
TypeError: ord() expected a character, but string of length 2 found
另外,使用for
循环和range()
执行此操作会非常复杂,我建议使用while
循环并检查直到起始字符成为结束字符。
执行此操作的一种方法是获取最后一个元素,检查其Z
是否将其更改为A
并在其之前增加元素。否则,按ord()
增加1
增量,然后使用chr()
获取该字符。
适用于任意大小字符的算法示例 -
def resolve(item):
start = int(re.search(r'\d+', item[0]).group())
c = re.search(r'[a-zA-Z]+', item[0]).group()
d = re.search(r'[a-zA-Z]+', item[1]).group()
print(c, d)
s = c
yield s + str(start)
while s != d:
ls = len(s) - 1
news = ""
for i in range(ls,-1,-1):
c = s[i]
if c.upper() == 'Z':
news += 'A'
else:
news += chr(ord(c) + 1)
break
s = s[:i] + news[::-1]
yield s + str(start)
示例/演示 -
>>> def resolve(item):
... start = int(re.search(r'\d+', item[0]).group())
... c = re.search(r'[a-zA-Z]+', item[0]).group()
... d = re.search(r'[a-zA-Z]+', item[1]).group()
... print(c, d)
... s = c
... yield s + str(start)
... while s != d:
... ls = len(s) - 1
... news = ""
... for i in range(ls,-1,-1):
... c = s[i]
... if c.upper() == 'Z':
... news += 'A'
... else:
... news += chr(ord(c) + 1)
... break
... s = s[:i] + news[::-1]
... yield s + str(start)
...
>>>
>>> xx = resolve(['AX95', 'BD95'])
>>>
>>> print(list(xx))
AX BD
['AX95', 'AY95', 'AZ95', 'BA95', 'BB95', 'BC95', 'BD95']
答案 1 :(得分:1)
你在这里:)
import re
def resolve(item):
print (item)
num = int(re.search(r'\d+', item[0]).group())
p11 = re.search(r'(\w)(\w)', item[0]).group(1)
p12 = re.search(r'(\w)(\w)', item[0]).group(2)
p21 = re.search(r'(\w)(\w)', item[1]).group(1)
p22 = re.search(r'(\w)(\w)', item[1]).group(2)
print (p11, p12, p21, p22)
for word in range(ord(p11), ord(p21) + 1):
for word2 in range(ord(p12) if ord(p11) == word else ord('A'), (ord(p22) if ord(p21) == word else ord('Z')) + 1):
yield chr(word) + chr(word2) + str(num)
答案 2 :(得分:1)
这是一种替代方法,也应该应对翻滚。
首先从开始和结束范围中分割出字母和数字。然后将两个字母组转换为基数为27的数字。目的是简单地从头到尾计算。
然后使用Python itertools.product
创建一个AA
到ZZ
的序列,其中itertools.islice
提供必要的范围。
为什么选择27岁?这是一种类似于处理前导零的解决方法。即将AA
和AAA
转换为基数26会得到相同的值。
import string, itertools, re
def convert_to_range(chars):
value = 0
for index, unit in enumerate([ord(x) - 64 for x in reversed(chars)]):
value += unit * (27 ** index)
return value
def resolve(item):
start_split = re.split("(\d+)", item[0])
end_split = re.split("(\d+)", item[1])
trailing = end_split[1]
start = convert_to_range(start_split[0])
end = convert_to_range(end_split[0])
cols = [' '+string.ascii_uppercase] * len(end_split[0])
for x in itertools.islice(itertools.product(*cols), start, end+1):
step = "".join(x).lstrip(" ")
if ' ' in step:
continue
yield step + trailing
print(list(resolve(['AX95', 'BD95'])))
print(list(resolve(['X95', 'AA95'])))
print(list(resolve(['ZX95', 'AAB95'])))
这会给你:
['AX95', 'AY95', 'AZ95', 'BA95', 'BB95', 'BC95', 'BD95']
['X95', 'Y95', 'Z95', 'AA95']
['ZX95', 'ZY95', 'ZZ95', 'AAA95', 'AAB95']