将元素弹出堆栈的 pythonic 方法 (collections.deque)
pythonic way to pop elements out of stack (collections.deque)
TL;DR: 请参阅底部的代码。
我正在实施 Reverse Polish Notation calculator in Python, using the collections.deque 堆栈实施。
因为我也在处理具有多个参数的函数,所以我使用了一个分隔符,放在实际参数之前。例如,给定以下表达式作为输入:max(2, 3, 4)
,Shunting Yard 算法生成以下可迭代对象:['|', '2', '3', '4', 'max']
.
当我遍历它时,分隔符和数字被压入堆栈;如果遇到函数,分隔符之前的所有元素都"popped"出栈并附加到列表中。
是否有更pythonic的方法来弹出堆栈末尾的元素达到特定条件?
到目前为止我的代码:
args = []
while op_stack[-1] != FUNC_ARGS_SEPARATOR:
args.append(op_stack.pop())
你得到的很好;没有合理的方法可以使用迭代器协议完成此任务(这通常是您清理此类内容的方式)。
理论上,如果您翻转 op_stack
的顺序(因此顶部在左侧,而不是右侧),您也许可以使用 .index
找到分隔符,然后做一个批量切片和 args.extend
,然后做一个批量 del
切片,但这几乎不值得麻烦(尤其是当分隔符可能相对较快地找到时)。
这是另一个使用迭代器的解决方案。我不会将其称为对您当前解决方案的改进,但它是不同的。
from collections import deque
import itertools
d = deque(["|", "2", "3", "4", "max"])
args = list(
itertools.takewhile(
# Check if elt is a separator.
# Side-effect: append separator if encountered.
lambda elt: elt != "|" or d.append(elt),
# Pop forever.
(d.pop() for _ in itertools.repeat(None)),
)
)
在朋友的帮助下,我们最终将 iter 关键字与 sep
作为 sentinel:
from collections import deque
sep = "|"
op_stack = deque([sep, 2, 3, 4])
args = iter(op_stack.pop, sep)
print(list(args))
这应该是解决这个问题的最 pythonic 和 KISS 方法之一,所以我将接受这个作为答案。
感谢大家的帮助!
TL;DR: 请参阅底部的代码。
我正在实施 Reverse Polish Notation calculator in Python, using the collections.deque 堆栈实施。
因为我也在处理具有多个参数的函数,所以我使用了一个分隔符,放在实际参数之前。例如,给定以下表达式作为输入:max(2, 3, 4)
,Shunting Yard 算法生成以下可迭代对象:['|', '2', '3', '4', 'max']
.
当我遍历它时,分隔符和数字被压入堆栈;如果遇到函数,分隔符之前的所有元素都"popped"出栈并附加到列表中。
是否有更pythonic的方法来弹出堆栈末尾的元素达到特定条件? 到目前为止我的代码:
args = []
while op_stack[-1] != FUNC_ARGS_SEPARATOR:
args.append(op_stack.pop())
你得到的很好;没有合理的方法可以使用迭代器协议完成此任务(这通常是您清理此类内容的方式)。
理论上,如果您翻转 op_stack
的顺序(因此顶部在左侧,而不是右侧),您也许可以使用 .index
找到分隔符,然后做一个批量切片和 args.extend
,然后做一个批量 del
切片,但这几乎不值得麻烦(尤其是当分隔符可能相对较快地找到时)。
这是另一个使用迭代器的解决方案。我不会将其称为对您当前解决方案的改进,但它是不同的。
from collections import deque
import itertools
d = deque(["|", "2", "3", "4", "max"])
args = list(
itertools.takewhile(
# Check if elt is a separator.
# Side-effect: append separator if encountered.
lambda elt: elt != "|" or d.append(elt),
# Pop forever.
(d.pop() for _ in itertools.repeat(None)),
)
)
在朋友的帮助下,我们最终将 iter 关键字与 sep
作为 sentinel:
from collections import deque
sep = "|"
op_stack = deque([sep, 2, 3, 4])
args = iter(op_stack.pop, sep)
print(list(args))
这应该是解决这个问题的最 pythonic 和 KISS 方法之一,所以我将接受这个作为答案。
感谢大家的帮助!