用于弹出元素的pythonic方法(collections.deque)

时间:2018-06-02 12:25:27

标签: python python-3.x deque

TL; DR:见底部的代码。

我正在使用Reverse Polish Notation calculator堆栈实现在Python中实现collections.deque

由于我也在处理具有多个参数的函数的情况,因此我使用了一个在实际参数之前放置的分隔符号。例如,给定以下表达式作为输入:max(2, 3, 4)Shunting Yard算法生成以下可迭代:['|', '2', '3', '4', 'max']

当我迭代它时,分隔符和数字被压入堆栈;如果遇到一个函数,直到分隔符的所有前面的元素都会从堆栈中“弹出”并附加到列表中。

是否有更多的pythonic方法可以将元素从堆栈末尾弹出到某个条件? 到目前为止我的代码:

args = []
while op_stack[-1] != FUNC_ARGS_SEPARATOR:
    args.append(op_stack.pop())

3 个答案:

答案 0 :(得分:1)

你得到的很好;没有合理的方法来使用迭代器协议来完成这个任务(这通常就是你要清理这样的东西)。

理论上,如果你翻转op_stack的顺序(所以顶部位于左侧,而不是右侧),您可以使用.index找到分隔符,然后执行一个批量切片和args.extend,然后是批量del切片,但它几乎不值得麻烦(特别是当相对较快地找到分隔符时)。

答案 1 :(得分:1)

这是迭代器的另一个解决方案。我不认为这是对当前解决方案的改进,但它是不同的。

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

答案 2 :(得分:0)

在朋友的帮助下,我们将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方式之一,所以我将接受这个作为答案。

感谢帮助人员!