基于 Python 中的其他字符串生成字符串
String generation based on the other string in Python
我想创建一个简单的字符串生成器,下面是它的工作原理
- 我声明一个
pattern_string = "abcdefghijklmnopqrstuvwxyz"
- 我的起始字符串可以说
starting_string = "qywtx"
- 现在我想生成如下字符串:
- 根据模式字符串检查我的
starting_string
中的最后一个字符。
最后一个字符是 x
。我们在find it in the pattern_string
中找到这个字符:
abcdefghijklmnopqrstuvw x yz
看到下一个字符是 y
所以我想要输出 qywty
。
...
但是,当我到达 z 时,我希望我的字符串增加倒数第二个字符并将最后一个字符设置为 starting_pattern
的第一个字符,因此它将是 qywra
等等...
现在提问:
我可以使用 REGEX 来实现吗?
是否有已经处理此类生成的库?
下面会根据你的描述生成下一个字符串
def next(s, pat):
l = len(s)
for i in range(len(s) - 1, -1, -1): # find the first non-'z' from the back
if s[i] != pat[-1]: # if you find it
# leave everything before i as is, increment at i, reset rest to all 'a's
return s[:i] + pat[pat.index(s[i]) + 1] + (l - i - 1) * pat[0]
else: # this is only reached for s == 'zzzzz'
return (l + 1) * pat[0] # and generates 'aaaaaa' (just my assumption)
>>> import string
>>> pattern = string.ascii_lowercase # 'abcde...xyz'
>>> s = 'qywtx'
>>> s = next(s, pattern) # 'qywty'
>>> s = next(s, pattern) # 'qywtz'
>>> s = next(s, pattern) # 'qywua'
>>> s = next(s, pattern) # 'qywub'
最后为多个'z'
:
>>> s = 'foozz'
>>> s = next(s, lower) # 'fopaa'
对于所有 'z',从增加长度的 'a' 开始:
>>> s = 'zzz'
>>> s = next(s, lower) # 'aaaa'
据我所知,没有库函数可以做到这一点。接近的是 itertools.product
:
>>> from itertools import product
>>> list(map(''.join, product('abc', repeat=3)))
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa',
'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab',
'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']
但这不适用于任意起始字符串。可以通过将它与 itertools.dropwhile
组合来模仿这种行为,但是跳过开始字符串之前的所有组合会带来严重的开销(在字母表 26 和接近尾部的开始字符串的情况下,几乎呈现方法没用):
>>> list(dropwhile(lambda s: s != 'bba', map(''.join, product('abc', repeat=3))))
['bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']
我想创建一个简单的字符串生成器,下面是它的工作原理
- 我声明一个
pattern_string = "abcdefghijklmnopqrstuvwxyz"
- 我的起始字符串可以说
starting_string = "qywtx"
- 现在我想生成如下字符串:
- 根据模式字符串检查我的
starting_string
中的最后一个字符。 最后一个字符是
x
。我们在find it in thepattern_string
中找到这个字符:abcdefghijklmnopqrstuvw x yz
看到下一个字符是
y
所以我想要输出qywty
。 ...
但是,当我到达 z 时,我希望我的字符串增加倒数第二个字符并将最后一个字符设置为 starting_pattern
的第一个字符,因此它将是 qywra
等等...
现在提问:
我可以使用 REGEX 来实现吗?
是否有已经处理此类生成的库?
下面会根据你的描述生成下一个字符串
def next(s, pat):
l = len(s)
for i in range(len(s) - 1, -1, -1): # find the first non-'z' from the back
if s[i] != pat[-1]: # if you find it
# leave everything before i as is, increment at i, reset rest to all 'a's
return s[:i] + pat[pat.index(s[i]) + 1] + (l - i - 1) * pat[0]
else: # this is only reached for s == 'zzzzz'
return (l + 1) * pat[0] # and generates 'aaaaaa' (just my assumption)
>>> import string
>>> pattern = string.ascii_lowercase # 'abcde...xyz'
>>> s = 'qywtx'
>>> s = next(s, pattern) # 'qywty'
>>> s = next(s, pattern) # 'qywtz'
>>> s = next(s, pattern) # 'qywua'
>>> s = next(s, pattern) # 'qywub'
最后为多个'z'
:
>>> s = 'foozz'
>>> s = next(s, lower) # 'fopaa'
对于所有 'z',从增加长度的 'a' 开始:
>>> s = 'zzz'
>>> s = next(s, lower) # 'aaaa'
据我所知,没有库函数可以做到这一点。接近的是 itertools.product
:
>>> from itertools import product
>>> list(map(''.join, product('abc', repeat=3)))
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa',
'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab',
'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']
但这不适用于任意起始字符串。可以通过将它与 itertools.dropwhile
组合来模仿这种行为,但是跳过开始字符串之前的所有组合会带来严重的开销(在字母表 26 和接近尾部的开始字符串的情况下,几乎呈现方法没用):
>>> list(dropwhile(lambda s: s != 'bba', map(''.join, product('abc', repeat=3))))
['bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']