python如何连续查找字符串_如何使用python查找连续字符串

{a1的例子显示了如何在一个连续的序列中找到一个。引用:Find runs of consecutive numbers using groupby. The key to the

solution is differencing with a range so that consecutive numbers all

appear in same group.

出于某种奇怪的原因,这个例子在后来的文档版本中没有出现。该代码适用于数字序列,下面的代码展示了如何调整它来处理字母。在from itertools import groupby

s = 'jaghiuuabc'

def keyfunc(t):

''' Subtract the character's index in the string

from its Unicode codepoint number.

'''

i, c = t

return ord(c) - i

a = []

for k, g in groupby(enumerate(s), key=keyfunc):

# Extract the chars from the (index, char) tuples in the group

seq = [t[1] for t in g]

if len(seq) > 1:

a.append(''.join(seq))

print(a)

输出

^{pr2}$

工作原理

这个代码的核心是groupby(enumerate(s), key=keyfunc)

^{}为s中的每个字符生成包含索引号和字符的元组。例如:s = 'ABCEF'

for t in enumerate(s):

print(t)

输出(0, 'A')

(1, 'B')

(2, 'C')

(3, 'E')

(4, 'F')

^{}从序列或迭代器中获取项,并将相邻的相等项聚合为组。默认情况下,它只是比较这些项的值,看它们是否相等。但你也可以给它一个关键功能。执行此操作时,它将每个项传递给键函数,并将该键函数返回的结果用于其相等性测试。在

下面是一个简单的例子。{cd5>我们先用一个除法来定义一个整数。这基本上去掉了数字中的最后一个数字。在def div_by_10(n):

return n // 10

a = [2, 5, 10, 13, 17, 21, 22, 29, 33, 35]

b = [div_by_10(u) for u in a]

print(a)

print(b)

输出[2, 5, 10, 13, 17, 21, 22, 29, 33, 35]

[0, 0, 1, 1, 1, 2, 2, 2, 3, 3]

因此,如果我们使用div_by_10作为groupby的关键函数,它将忽略每个数字中的最后一个数字,因此,如果相邻的数字只在最后一个数字上有所不同,它就会将它们组合在一起。在from itertools import groupby

def div_by_10(n):

return n // 10

a = [2, 5, 10, 13, 17, 21, 22, 29, 33, 35]

print(a)

for key, group in groupby(a, key=div_by_10):

print(key, list(group))

输出[2, 5, 10, 13, 17, 21, 22, 29, 33, 35]

0 [2, 5]

1 [10, 13, 17]

2 [21, 22, 29]

3 [33, 35]

My keyfunc接收一个(index_number,character)元组,并从字符的代码号中减去该索引_号并返回结果。让我们看看这对我前面的'ABCEF'的示例有何作用:def keyfunc(t):

i, c = t

return ord(c) - i

for t in enumerate('ABCEF'):

print(t, keyfunc(t))

输出(0, 'A') 65

(1, 'B') 65

(2, 'C') 65

(3, 'E') 66

(4, 'F') 66

对于代码,我们用65减去代码。但我们跳过了“D”,所以当我们对“E”和“F”做减法时,我们得到了66。这就是groupby如何将“A”、“B”、“C”放在一个组中,“E”和“F”放在下一组中。在

这可能是个棘手的问题。别指望马上就能完全理解。但如果你自己做一些实验,我相信它会逐渐深入人心。;)

为了好玩,下面是该代码的不可读的多嵌套列表理解版本。;)print([z for _, g in groupby(enumerate(s),lambda t:ord(t[1])-t[0])for z in[''.join([*zip(*g)][1])]if len(z)>1])

这是另一个受Amit Tripathi's answer启发的版本。这个不使用任何导入,因为它手动进行分组。prev包含前一个字符的码位号。我们将prev初始化为-2,这样在第一次执行if i != prev + 1测试时,它保证为真,因为ord(ch)的最小可能值为零,因此将向groups添加一个新的空列表。在s = 'jaghiuuabcxyzq'

prev, groups = -2, []

for ch in s:

i = ord(ch)

if i != prev + 1:

groups.append([])

groups[-1].append(ch)

prev = i

print(groups)

a = [''.join(u) for u in groups if len(u) > 1]

print(a)

输出[['j'], ['a'], ['g', 'h', 'i'], ['u'], ['u'], ['a', 'b', 'c'], ['x', 'y', 'z'], ['q']]

['ghi', 'abc', 'xyz']

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值