Clojure相当于Python的“any”和“all”函数?

时间:2011-10-24 04:26:53

标签: python clojure

Clojure中是否内置了类似于Python的anyall函数的函数?

例如,在Python中,它是all([True, 1, 'non-empty string']) == True

2 个答案:

答案 0 :(得分:41)

(every? f data) [docs] all(f(x) for x in data)相同。

(some f data) [docs] any(f(x) for x in data)类似,只是它返回f(x)的值(必须是真实的),而不是只是true

如果你想要与Python完全相同的行为,你可以使用identity函数,它只返回它的参数(相当于(fn [x] x))。

user=> (every? identity [1, true, "non-empty string"])
true
user=> (some identity [1, true "non-empty string"])
1
user=> (some true? [1, true "non-empty string"])
true

答案 1 :(得分:3)

在clojure中andor与python的allany非常相似,但需要注意的是(就像clojure.core/some一样)它们会返回元素这将使它满意...因此你可以与boolean一起使用它来转换它

(boolean (or "" nil false)) ; "" is truthy in clojure
; => true
(boolean (and [] "" {} () 0)) ; also [], {}, () and 0 are truthy
; => true

我使用boolean代替true?,因为后者将返回true iff参数值为true ...所以boolean更类似于python的bool 1}}因为它评估了真实性

some& every?and& or是宏,所以如果你总是希望将结果转换为布尔值,你不能简单地做(def any (comp boolean or)),但你必须定义一个宏,如

(defmacro any [& v] `(boolean (or ~@v)))
(defmacro all [& v] `(boolean (and ~@v)))

作为宏的副作用/优点是,它们是懒惰/可以短路(就像python的and& or,但它们是中缀二进制运算符)

(any "" (/ 1 0))
; => true
(all nil (/ 1 0))
; => false

它们就像python的anyall,即使在没有参数的情况下调用

(any)
; => false
(all)
; => true

在python中:

>>> any([])
False    
>>> all([])
True

如果您希望使用单个列表/序列参数调用any / all,则可以执行以下操作:

(defmacro all [v] `(boolean (and ~@v)))

(all [])
; => true
(all [nil (/ 1 0)])    
; => false