如何基于条件python查找字符串中字母的位置

如何基于条件python查找字符串中字母的位置,python,string,list,Python,String,List,我想找到字符串中满足一定条件的字母的索引。如果字母前的所有括号都是完整的,我想找到字母g的索引 这就是我所拥有的 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:

我想找到字符串中满足一定条件的字母的索引。如果字母前的所有括号都是完整的,我想找到字母g的索引

这就是我所拥有的

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 as 39,这是最后一个索引,但是正确的答案应该是35,因为在第二个最后的g完成之前的括号中。

您可以使用.index来查找字符串或列表中的字符串或元素的索引


放置stringvar.indexstring这将为您提供字符串的偏移量或索引。

您可以使用.index查找字符串或列表中字符串或元素的索引


放置stringvar.indexstring这将为您提供字符串的偏移量或索引。

保留您的想法,只需关闭一些功能,请参阅注释:

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

保留您的想法,只做了几件事,请参见评论:

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

@蒂埃里·拉特维尔的回答非常好。在这里,我只是建议一些小的变化,但并不声称它们更好:

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]

@蒂埃里·拉特维尔的回答非常好。在这里,我只是建议一些小的变化,但并不声称它们更好:

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]
您可以不使用正则表达式,只需使用堆栈来跟踪您的参数在迭代字符时是否平衡:

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]
在这里使用堆栈是检查平衡状态的经典方法。我已经有一段时间没有从头开始实现它了,所以可能有一些边缘案例我没有考虑。但这应该是一个良好的开端。我制作了一个生成器,但您可以将其设置为一个普通函数,返回索引列表,第一个这样的索引或最后一个这样的索引。

您可以省去正则表达式,只需使用堆栈在迭代字符时跟踪参数是否平衡:

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]

在这里使用堆栈是检查平衡状态的经典方法。我已经有一段时间没有从头开始实现它了,所以可能有一些边缘案例我没有考虑。但这应该是一个良好的开端。我制作了一个生成器,但您可以将其设置为一个普通函数,返回索引列表,第一个这样的索引或最后一个这样的索引。

这是在OP中更简单地采用代码,并考虑了条件计数\u open!=0:

输出:


这是在OP中更简单地采用代码,并考虑了条件count_open!=0:

输出:


当你第一次找到这封信的时候,你不会把它弄坏,所以它会一直到最后一封,这正是它所做的,对吗?我遗漏了什么吗?我一直在玩弄断点,但它们都给出了相同的结果。顺便说一句,您使用了位布尔and,而不是and。我相信在这种情况下,它们实际上是等价的,但是你应该使用and,如果你的意思是布尔and,并且只使用-,如果你想按位and。当你第一次找到这个字母时,你不会破坏它,所以它只会一直到最后一个字母,这正是它所做的,对吗?我遗漏了什么吗?我一直在玩弄断点,但它们都给出了相同的结果。顺便说一句,您使用了位布尔and,而不是and。我相信在这种情况下,它们实际上是等价的,但是你应该使用and,如果你是指布尔and,并且只使用-,如果你想要按位and。这不能通过解决我的问题,我在寻找它不能通过解决我的问题,我在寻找i@Triptych正如人们所说,这是一部老掉牙但很好的作品。当然,可以使用递归,但这只是用我的堆栈换取调用堆栈:是的,我写了一个递归版本只是为了练习/娱乐。堆叠更安全。这太完美了!谢谢,我希望函数返回字符串中指向平衡g的所有字母。我要补充一点:但这很有效,谢谢@三联画这是一部老掉牙的作品,但正如人们所说,这是一部好作品。当然,可以使用递归,但这只是用我的堆栈换取调用堆栈:是的,我写了一个递归版本只是为了练习/娱乐。堆叠更安全。这太完美了!谢谢,我希望函数返回字符串中指向平衡g的所有字母。我要补充一点:但这很有效,谢谢!谢谢@Thierry的解释,我同意第二种方法是一种有效的方法,但是它会在单词而不是字母上失败?如果文本是间隔的,并且有单词,我们就必须改变函数,对吗?还有,如果没有返回值,我将如何将这个func应用于数据帧。谢谢@Thierry的解释,我同意第二个是一个有效的方法,ho 它是否会在单词而不是字母上失败?如果文本是间隔的,并且有单词,我们就必须改变函数,对吗?此外,如果没有返回值,我将如何将此func应用于数据帧。