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)]