我正在尝试获取一个元组列表,其中包含字符串中所有括号集的索引.通过列表推导,我可以轻松地找到左右两个parens:
s = "12(34)567"
left_parens = [i for i,j in enumerate(s) if j == "("]
right_parens = left_parens = [i for i,j in enumerate(s) if j == ")"]
Run Code Online (Sandbox Code Playgroud)
将这些单独的列表转换为具有(左paren,右paren)对的元组列表的最合理的方法是使用zip函数.
parens = zip(right_parens,left_parens)
print(list(parens))
Run Code Online (Sandbox Code Playgroud)
从此我希望得到:
[(2,5)]
Run Code Online (Sandbox Code Playgroud)
但相反,我得到:
[(5,5)]
Run Code Online (Sandbox Code Playgroud)
即使我像这样切换订单:
parens = zip(left_parens,right_parens)
Run Code Online (Sandbox Code Playgroud)
结果仍然是[(5,5)].
我错过了什么?
问题出在这里:
right_parens = left_parens = [ ... ]
Run Code Online (Sandbox Code Playgroud)
您将两个列表设置为相同的内存区域; 他们现在是同一个名单.将它们分开:
left_parens = [i for i,j in enumerate(s) if j == "("]
right_parens = [i for i,j in enumerate(s) if j == ")"]
Run Code Online (Sandbox Code Playgroud)
延期
请注意,您的算法不适用于嵌套括号:
s = "1(2(34)56)7"
Run Code Online (Sandbox Code Playgroud)
输出:
[(1, 6), (3, 9)]
Run Code Online (Sandbox Code Playgroud)
你可以用一个计数器解决这个问题:每个Lparen的预增量,每个Rparen的后减量.使用其嵌套级别标记每个paren位置:
string 1(2(34)56)7(8)
marker -1-2--2--1-1-1
Run Code Online (Sandbox Code Playgroud)
从这里开始,从内向外移动:匹配2,从左到右(只有一对),然后是1(两对).编码留给学生练习.:-)从这里,你可以