Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从堆栈中弹出元素的Python方式(collections.deque)_Python_Python 3.x_Deque - Fatal编程技术网

从堆栈中弹出元素的Python方式(collections.deque)

从堆栈中弹出元素的Python方式(collections.deque),python,python-3.x,deque,Python,Python 3.x,Deque,TL;DR:请参阅底部的代码 我正在用Python实现一个,使用堆栈实现 因为我也在处理具有多个参数的函数的情况,所以我使用一个分隔符符号,将其放在实际参数之前。例如,给定以下表达式作为输入:max(2,3,4),该算法生成以下iterable:['|','2','3','4','max'] 当我迭代它时,分隔符和数字被推到堆栈上;如果遇到一个函数,则将从堆栈中“弹出”到分隔符之前的所有元素,并将其追加到列表中 是否有一种更具python风格的方式将元素从堆栈的末尾弹出到某个特定条件? 到目前为

TL;DR:请参阅底部的代码

我正在用Python实现一个,使用堆栈实现

因为我也在处理具有多个参数的函数的情况,所以我使用一个分隔符符号,将其放在实际参数之前。例如,给定以下表达式作为输入:
max(2,3,4)
,该算法生成以下iterable:
['|','2','3','4','max']

当我迭代它时,分隔符和数字被推到堆栈上;如果遇到一个函数,则将从堆栈中“弹出”到分隔符之前的所有元素,并将其追加到列表中

是否有一种更具python风格的方式将元素从堆栈的末尾弹出到某个特定条件? 到目前为止,我的代码是:

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

你所拥有的一切都很好;使用迭代器协议(通常是清理此类内容的方式)没有合理的方法来完成此任务


理论上,如果您翻转
op_堆栈的顺序(因此顶部在左侧,而不是右侧),您可能可以使用
.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)),
    )
)

在一位朋友的帮助下,我们以
sep
作为哨兵结束了关键词:

这应该是解决这个问题的最具python和KISS风格的方法之一,所以我将接受这个答案


谢谢大家的帮助!

你认为有没有办法把它转换成生成器?我不需要列表,因为我扩展了
args
var作为函数的输入。我在想一种方法,在堆栈上运行并生成弹出的元素。@AlbertoChiusole:takewhile
的问题是它是必要的Riy不仅获取并返回“take”元素,还获取并删除第一个不符合条件的元素。解决这一问题需要滥用过滤函数(那些有副作用的,如Yakym的回答,这违反了人们的普遍期望,即功能性编程工具,
itertools
模块基本上就是没有副作用的)。你可以这样做,但它肯定不是更具python风格的。@AlbertoChiusole:你可以制作某种特定于
deque
(它可以在任何可变序列类型上工作,只是不能在任意的iterables上工作),但同样,不是一种特别python风格的方法:
def popintil(filt,seq):而seq和filt(seq[-1]):yield seq.pop()
drop
list
获取迭代器。
from collections import deque

sep = "|"
op_stack = deque([sep, 2, 3, 4])

args = iter(op_stack.pop, sep)

print(list(args))