如何根据条件查找字符串中的位置python
我想查找字符串中满足一定条件的字母索引。如果字母前的所有括号都是完成。如何根据条件查找字符串中的位置python
这是我
sen = 'abcd(fgji(l)jkpg((jgsdti))khgy)ghyig(a)gh'
这是我做了什么
lst = [(i.end()) for i in re.finditer('g', sen)]
# lst
# [7, 16, 20, 29, 32, 36, 40]
count_open = 0
count_close = 0
for i in lst:
sent=sen[0:i]
for w in sent:
if w == '(':
count_open += 1
if w == ')':
count_close += 1
if count_open == count_close && count_open != 0:
c = i-1
break
这是给我的C为39,这是最后一个指标,但正确的答案应该是35作为第二个最后g之前的括号完成。
您可以免除regex
,简单地使用堆栈跟踪你的括号是否是平衡的,而你遍历字符:
In [4]: def find_balanced_gs(sen):
...: stack = []
...: for i, c in enumerate(sen):
...: if c == "(":
...: stack.append(c)
...: elif c == ")":
...: stack.pop()
...: elif c == 'g':
...: if len(stack) == 0:
...: yield i
...:
In [5]: list(find_balanced_gs(sen))
Out[5]: [31, 35, 39]
在这里使用堆栈是检查均衡parans的“经典”方法。自从我从头开始实施它已经有一段时间了,所以可能会有一些我没有考虑过的边缘案例。但这应该是一个好的开始。我已经创建了一个生成器,但是你可以使它成为一个正常的函数,返回一个索引列表,第一个这样的索引或最后一个这样的索引。
您可以使用.index()查找字符串或列表中字符串或元素的索引。
把stringvar.index(字符串)这会给你的字符串的偏移量或索引。
这并不能解决我的问题,我正在寻找我 –
保持你的想法,只是几个事情了,看评论:
import re
sen='abcd(fgji(l)jkpg((jgsdti))khgy)ghyig(a)gh'
lst=[ (i.end()) for i in re.finditer('g', sen)]
#lst
#[7, 16, 20, 29, 32, 36, 40]
for i in lst:
# You have to reset the count for every i
count_open= 0
count_close=0
sent=sen[0:i]
for w in sent:
if w=='(':
count_open+=1
if w==')':
count_close+=1
# And iterate over all of sent before comparing the counts
if count_open == count_close & count_open != 0:
c=i-1
break
print(c)
# 31 - actually the right answer, not 35
但是,这是不是很有效,因为你的字符串相同的部分在迭代多次。你可以把它更加高效,在遍历字符串只有一次:
sen='abcd(fgji(l)jkpg((jgsdti))khgy)ghyig(a)gh'
def find(letter, string):
count_open = 0
count_close = 0
for (index, char) in enumerate(sen):
if char == '(':
count_open += 1
elif char == ')':
count_close += 1
elif char == letter and count_close == count_open and count_open > 0:
return index
else:
raise ValueError('letter not found')
find('g', sen)
# 31
find('a', sen)
# ...
# ValueError: letter not found
谢谢@Thierry对于这个解释,我同意第二个是一个有效的方法,但是它会失败,而不是字母?如果文字间隔并有文字,我们将不得不改变功能?另外,如果没有返回值,我将如何将这个func应用于数据框。 –
@Thierry Lathuille的答案是非常好的。在这里,我只是提出一些微小的变化,但并未声称他们是更好的:
out = [] # collect all valid 'g'
ocount = 0 # only store the difference between open and closed
for m in re.finditer('[\(\)g]', sen): # use re to preselect
L = m.group()
ocount += {'(':1, ')':-1, 'g':0}[L] # save a bit of typing
assert ocount >= 0 # enforce some grammar if you like
if L == 'g' and ocount == 0:
out.append(m.start())
out
# [31, 35, 39]
这是一个简单的采用在OP代码(并考虑到条件count_open != 0
):
def get_idx(f, sen):
idx = []
count_open= 0
count_close=0
for i, w in enumerate(sen):
if w == '(':
count_open += 1
if w == ')':
count_close += 1
if count_open == count_close & count_open != 0:
if w == f:
idx.append(i)
return idx
get_idx('g', sen)
日期:
[31, 35, 39]
当你发现你信不破这是第一次,直到最后一次,这正是它在做什么,对吧?我错过了什么吗? –
我一直在玩休息时间,但他们都给出了相同的结果 –
顺便说一句,你已经使用了按位布尔和,'&'而不是'和'。我相信在这种情况下,它们将实际上是等价的,但如果您的意思是布尔型,则应该使用'和',并且如果要按位和,则只使用'&'。 –