识别 Python 中的子字符串(在字符串中沿索引移动)- 只能将 str(不是 "int")连接到 str

Identifying a substring in Python (moving along indices within a string) - can only concatenate str (not "int") to str

我是 Python 和编码的新手,一直坚持将子字符串与另一个字符串进行比较。

我有: 字符串 sq 和模式 STR.

目标:我正在尝试计算连续出现在该字符串中的 STR 模式的最大数量。

这是部分代码:

 STR = key
        counter = 0
        maximum = 0

        for i in sq:
            while sq[i:i+len(STR)] == STR:
                counter += 1
                i += len(STR)

问题似乎出现在“while部分”,说TypeError: can only concatenate str (not "int") to str.

我看到它将 i 视为一个字符,将 len(STR) 视为一个整数,但我不知道如何解决这个问题。 思路是取第一个等于STR长度的子串,判断这个子串和STR模式是否相同。

谢谢!

通过循环使用:

for i in sq:

您正在遍历 sq 元素

如果您希望变量 i 遍历 sq 的可能 索引 ,您通常会遍历 range(len(sq)),这样你就可以得到从 0len(sq) - 1.

的值
for i in range(len(sq)):

但是,在这种情况下,您希望在循环内分配给 i

i += len(STR)

如果您在 range(...) 上循环,这将不会产生预期的效果,因为在下一次迭代中它将被分配给 range 的下一个值,忽略添加的增量。通常不应在循环内分配给循环变量。

所以它可能最容易用 while 循环实现,并且您显式设置 i 的所需值(i=0 初始化,i+=1 之前重新启动循环),然后您可以在循环内进行任何其他您想要的分配。

STR = "ell"
sq = "well, well, hello world"

counter = 0

i = 0
while i < len(sq):
    while sq[i:i+len(STR)] == STR:  # re use of while here, see comments
        counter += 1
        i += len(STR)
    i += 1

print(counter)  # prints 3

(您或许可以将 len(sq)len(STR) 保存在其他变量中,以节省重复计算它们的时间。)

此解决方案不使用 for,因此增量可以在不匹配时增加 1,在匹配时增加字符串长度。任何不匹配记录到目前为止看到的最大计数并重置计数。

def count_max(string,key):

    if len(key) > len(string):
        return 0

    last = len(string) - len(key)
    i = 0
    count = 0
    maximum = 0

    while i <= last:
        if string[i:i+len(key)] == key:
            count += 1
            i += len(key)
        else:
            maximum = max(maximum,count)
            count = 0
            i += 1
    return max(maximum,count)

key = 'abc'
strings = 'ab','abc','ababcabc','abcdefabcabc','abcabcdefabc'

for string in strings:
    print(count_max(string,key))

输出:

0
1
2
2
2

这里还有一个可能更快的版本。对于短字符串,它并不快,但如果字符串很长,它会快得多,因为正则表达式将比 Python 循环更快地找到匹配项。

def count_max2(string,key):
    return max([len(match) // len(key)
                for match in re.findall(rf'(?:{re.escape(key)})+',string)]
               ,default=0)

工作原理:

  • re.escape 是一个函数,用于确保 key 中的字符按字面意思获取,而不是正则表达式语法。例如,允许搜索 +,而不是被视为“一个或多个”匹配项。
  • rf'' 是原始 f-string(格式字符串)的语法。 “raw”被推荐用于正则表达式,因为表达式的某些语法会与其他 Python 语法混淆。 f-strings 允许使用大括号 {}.
  • 将变量和函数插入到字符串中
  • re.findall 查找字符串中的所有连续匹配项。
  • [f(x) for x in iterable] 是一个 list comprehension 并获取从 iterable 返回的列表并计算列表中每个项目的函数。在这种情况下,如果用匹配的长度除以键的长度得到键的出现次数。
  • max(iterable,default=0) returns iterable 的最大值,如果 iterable 为空(无匹配项)则为 0。