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