假设一个字符串s
可能包含几个相邻的破折号。为简单起见,让我们将这些事件中的每一个称为“重复动机”。例如,以下字符串s
包含五个重复的破折号动机,即长度为3,2,6,5和1。
s = "abcde---fghij--klmnopq------rstuvw-----xy-z"
我正在尝试提出Python代码,它返回每个重复动机的字符串中的相应长度和相应位置。优先地,代码返回一个元组列表,每个元组的格式(长度,位置)。
sought_function(s)
# [(3,5), (2,13), (6,22), (5,34), (1,41)]
您对如何启动此代码有任何建议吗?
答案 0 :(得分:5)
您可以使用groupby
:
s = "abcde---fghij--klmnopq------rstuvw-----xy-z"
from itertools import groupby
[(next(g)[0], sum(1 for _ in g) + 1) for k, g in groupby(enumerate(s), lambda x: x[1]) if k == "-"]
# [(5, 3), (13, 2), (22, 6), (34, 5), (41, 1)]
或者@Willem发表评论时,将sum
替换为len
:
[(next(g)[0], len(list(g)) + 1) for k, g in groupby(enumerate(s), lambda x: x[1]) if k == "-"]
# [(5, 3), (13, 2), (22, 6), (34, 5), (41, 1)]
答案 1 :(得分:1)
如果你想编写自己的函数:只需遍历字符,并在内存中保存当前长度,如果序列被截断,则产生元素:
def find_sequences(s,to_find):
result = []
lng = 0
for i,c in enumerate(s):
if c == to_find:
lng += 1
else:
if lng:
result.append((lng,i-lng))
lng = 0
if lng:
result.append((lng,i-lng))
return result
所以s
是字符串,to_find
是您感兴趣的字符(此处为'-'
)。
答案 2 :(得分:0)
如果使用numpy很好:
import numpy as np
a = "abcde---fghij--klmnopq------rstuvw-----xy-z"
bool_vec = np.array([letter == "-" for letter in a])
dots = np.where(np.diff(bool_vec)!=0)[0] + 1
number = np.diff(dots.reshape((-1,2)),1).ravel()
idx = dots[::2]
number
和idx
两个数组包含您想要的内容:)
答案 3 :(得分:0)
你可以re.split("(-+)", s)
返回[" abcde"," ---",...]的列表,然后迭代它。
答案 4 :(得分:0)
以下是我的建议:
import re
s = "abcde---fghij--klmnopq------rstuvw-----xy-z"
list1= []
for x in re.findall("[a-z]*-", s):
temp = x.strip("-")
if len(temp) > 0:
list1.append(temp)
print(list1)