gpt4 book ai didi

clojure - 模仿 Python 产量的惯用 Clojure 方式

转载 作者:行者123 更新时间:2023-12-02 16:48:16 27 4
gpt4 key购买 nike

我正在迭代一个列表,边走边建立状态,偶尔当我遇到某个哨兵时,我会返回一个结果。如果我在 Python 中执行此操作,我会懒洋洋地yield结果,跟踪函数本地范围内的状态:

# this is simplified for illustration
def yielder(input_list):
state = 0
for item in input_list:
if item = 'SENTINEL':
yield state * 2
state = 0
else:
state += item

yielder([1, 5, 2, 5, 'SENTINEL', 4, 6, 7]) # [26, 34]

我的第一个实现使用 reduce,但这不如 yield 因为:

  • 我在迭代之间传递的值既有循环状态,又有我想要产生的项目,这看起来很笨拙
  • 这并不懒

iterate 可以用来缓解后者,但我实际上不想为每个输入项返回一些东西,所以它需要更多的修改。

在 Clojure 中执行此操作的惯用方法是什么?

最佳答案

您可以使用您提到的lazy-seq自行构建它,或者您可以使用partitionreduce将问题分成多个阶段,然后将它们线程在一起。我将使用 thread-last 宏来单独显示每个步骤:

user> (->> [1, 5, 2, 5, :SENTINEL, 4, 6, 7] ;; start with data
(partition-by #(= :SENTINEL %)) ;; ((1 5 2 5) (:SENTINEL) (4 6 7))
(take-nth 2) ;; ((1 5 2 5) (4 6 7))
(map #(* 2 (reduce + %)))) ;; the map here keeps it lazy
(26 34)

这里直接使用lazy-seq:

user>  (defn x [items]
(when (seq items)
(lazy-seq (cons (* 2 (reduce + (take-while #(not= :SENTINEL %) items)))
(x (rest (drop-while #(not= :SENTINEL %) items)))))))
#'user/x
user> (x [1, 5, 2, 5, :SENTINEL, 4, 6, 7])
(26 34)

关于clojure - 模仿 Python 产量的惯用 Clojure 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21436677/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com