Python 列出理解以查找匹配的参数

Python 列出理解以查找匹配的参数,python,list-comprehension,Python,List Comprehension,我正试图提出一个列表理解,它将匹配打开和关闭参数。到目前为止,我有这两个语句,分别获取了打开和关闭参数的两个列表 my_str = "hanz(and(franz/bob())+ 7) + tom(2)" 抓取打开参数的idx: [ i for i,c in enumerate(my_str) if c == '('] # [4, 8, 18, 31] 抓取闭合参数的idx: [ i for i,c in enumerate(my_str) if c == ')'] # [19, 20,

我正试图提出一个列表理解,它将匹配打开和关闭参数。到目前为止,我有这两个语句,分别获取了打开和关闭参数的两个列表

my_str = "hanz(and(franz/bob())+ 7) + tom(2)"
抓取打开参数的idx:

[ i for i,c in enumerate(my_str) if c == '(']

# [4, 8, 18, 31]
抓取闭合参数的idx:

[ i for i,c in enumerate(my_str) if c == ')']

# [19, 20, 24, 33]
我想要的是一个方便的理解,可以给我一个对应于每对配对的配对列表

i、 e


就像@Tordek提到的,虽然不是不可能,但这不是很实际

然而,为了完整起见,这里有一个解决方案:

my_str = "hanz(and(franz/bob())+ 7) + tom(2)"

 pt_arr = [ 1 if c == '(' else -1 for i,c in enumerate(my_str ) if c == ')' or c == '(']
idx_arr = [ i for i,c in enumerate(my_str ) if c == ')' or c == '(']

[(idx_arr[strt_idx],idx_arr[strt_idx + [j for j,d in enumerate([ sum(pt_arr[strt_idx:i + 1]) for i,c in enumerate(pt_arr) if i >= strt_idx]) if d == 0][0]]) for strt_idx,f in enumerate(pt_arr) if f == 1]

# [(4,24), (8,20), (18,19), (31,33)]

如注释中所述,正确且简单的方法是使用堆栈:

my_str = "hanz(and(franz/bob())+ 7) + tom(2)"
stack = []
parens = []
for i, c in enumerate(my_str):
    if c == "(":
        stack.append(i)
    elif c == ")":
        parens.append((stack.pop(), i))
print(parens) # [(18, 19), (8, 20), (4, 24), (31, 33)]
但是,如果你看重一行代码而不是可读性或编码约定,你也可以将其塞进一个列表中,并产生副作用:

stack = []
parens = [(stack.pop(), i) for i, c in enumerate(my_str)
          if c == "(" and stack.append(i) or c == ")"]
print(parens) # [(18, 19), (8, 20), (4, 24), (31, 33)]
这使用了这样一个事实,即
以及
是短路评估的,因此只有当
c==”(“
)时,它才会
附加
项,但随后会失败,因为
附加
返回
,并且只有在第二个条件
c==”
为真时,才会向结果中添加元素,从堆栈中弹出最近的
的位置


至少,这不是对列表理解的完全滥用,因为结果不是被丢弃的,而是实际期望的结果,而且它可能比三个列表理解更容易理解(虽然它们没有副作用),但它是“方便”的更好解决方案实现这一点的方法是:使它成为一个函数,而不是不管它有多少行。

这并不是一个真正的列表理解工作;这是有原因的吗?使用循环和堆栈非常容易。
具有副作用。
让我崩溃了!而且这很有趣,因为它是真的
stack = []
parens = [(stack.pop(), i) for i, c in enumerate(my_str)
          if c == "(" and stack.append(i) or c == ")"]
print(parens) # [(18, 19), (8, 20), (4, 24), (31, 33)]