【问题标题】:For-loop returns same character in parsingFor循环在解析中返回相同的字符
【发布时间】:2016-06-18 22:19:55
【问题描述】:

我正在创建一个程序,它将拆分“单独对”的括号。例如()() 变成|()|()|(()) 保持不变,成为|(())|。它不断“获得”相同的字符。我尝试过更改插入位置,例如pos - 1,但仍然无法正常工作。这是我的代码:

def insert(source_str, insert_str, pos):
        return source_str[:pos]+insert_str+source_str[pos:]


x = 0 
rightSideOfEquation = "()bx((x))c(y(c+1)(x)y)"


for pos in range(len(rightSideOfEquation)):
    if x == 0:
        rightSideOfEquation = insert(rightSideOfEquation,'|',pos)
    if rightSideOfEquation[pos] == '(':
        x += 1
    if rightSideOfEquation[pos] == ')':
        x -= 1

print(rightSideOfEquation)

打印|||||||||||||||||||||||()bx((x))c(y(c+1)(x)y)
我希望它打印|()|bx|((x))|c|(y(c+1)(x)y)|

注意:您可以在此处查看: **https://math.stackexchange.com/questions/1682322/recursive-parsing-parenthesis-with-explanation
**我尝试将其更改为pos + 1pos -1,但效果不大,除了重复的地方。

【问题讨论】:

  • 如果是递归解析,你的递归在哪里?
  • x 永远是 0
  • 好吧,我不知道怎么解释,我只是说你可以在这里阅读更多内容:)
  • 在改变对象(或者,在这种情况下,重新分配其引用)时迭代可迭代的索引通常不是一个好主意。
  • 如果您能想到任何更好的方法,不胜感激!

标签: python parsing python-3.x for-loop parentheses


【解决方案1】:

在迭代对象时修改它总是会导致灾难。

您需要在迭代旧对象时构建一个新对象:

equation = "a()bx((x))c(y(c+1)(x)y)"
new_equation = []
parens = 0
for ch in equation:
    if ch == '(':
        if parens == 0:
            new_equation.append('|')
        new_equation.append(ch)
        parens += 1
    elif ch == ')':
        new_equation.append(ch)
        parens -= 1
        if parens == 0:
            new_equation.append('|')
    else:
        new_equation.append(ch)
equation = ''.join(new_equation)
print(equation)

这给出了:

a|()|bx|((x))|c|(y(c+1)(x)y)|

【讨论】:

  • 虽然这修复了开头打印的“|”,但仍然不正确(请注意开头多余的“|”和“bx”后面缺少的“|”和第一个“c”)。
  • @bbkglb:是的,很难从 OP 的要求中得出结论,但我怀疑你是对的。哦,修复了我的代码以匹配这些结果。
【解决方案2】:

你不想改变你正在迭代的东西。我通过创建输入字符串的副本修复了您的代码,它似乎正在工作:

def insert(source_str, insert_str, pos):
    return source_str[:pos]+insert_str+source_str[pos:]


x = 0 
rightSideOfEquation = "a()bx((x))c(y(c+1)(x)y)"
copy = rightSideOfEquation
posincopy = 0

for pos in range(len(rightSideOfEquation)):
    if rightSideOfEquation[pos] == '(':
        x += 1
        if x == 1:
            copy = insert(copy,'|',posincopy)
            posincopy = posincopy + 1
    if rightSideOfEquation[pos] == ')':
        x -= 1
        if x == 0:
            copy = insert(copy,'|',posincopy + 1)
            posincopy = posincopy + 1
    posincopy = posincopy + 1

print(copy)

输出:

a|()|bx|((x))|c|(y(c+1)(x)y)|

【讨论】:

  • 您的代码没有给出您在此处包含的输出。您的代码的输出是:|a|()|b|x|((x))|c|(y(c+1)(x)y)(请注意末尾缺少“|”)。另外,您正在打印一个额外的“|”一开始。
  • 我刚刚解决了这个问题。
  • 但现在它正在打印|a|()|b|x|((x))|c|(y(c+1)(x)y)|,其中有多个不应该存在的额外“|”...
【解决方案3】:

在这种情况下,使用“while”语句而不是 for 循环将使您的生活更轻松:

def insert(source_str, insert_str, pos):
    return source_str[:pos]+insert_str+source_str[pos:]

x = 0 
rightSideOfEquation = "a()bx((x))c(y(c+1)(x)y)"
pos = 0

while pos < len(rightSideOfEquation):
  if rightSideOfEquation[pos] == '(':
      if x==0:        
          rightSideOfEquation = insert(rightSideOfEquation,'|',pos)
          pos+=1
      x += 1
  elif rightSideOfEquation[pos] == ')':
      x -= 1
      if x == 0:
          rightSideOfEquation = insert(rightSideOfEquation,'|',pos + 1)
  pos+=1

print(rightSideOfEquation)

这将打印以下内容:

a|()|bx|((x))|c|(y(c+1)(x)y)|

虽然使用递归函数会更简洁、更容易,但我想向您展示如何修复现有代码中的错误,而不是完全改变您的思维过程...

【讨论】:

  • 请解释递归函数...希望代码尽可能干净!
  • 选择因为不涉及对象的副本
猜你喜欢
  • 1970-01-01
  • 2012-09-27
  • 2020-03-30
  • 2019-02-20
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
相关资源
最近更新 更多