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

问题描述 投票:0回答:2

Clojure 中是否有类似于 Python 的

any
all
函数的内置函数?

例如,在 Python 中,它是

all([True, 1, 'non-empty string']) == True

python clojure
2个回答
45
投票

(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

4
投票

在clojure中,

and
or
与Python的
all
any
非常相似,但需要注意的是(就像
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
,因为它评估真实性

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 的

any
all
,即使在没有参数的情况下调用

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

在Python中:

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

如果您更喜欢使用单个列表/序列参数来调用

any
/
all
,您可以简单地执行以下操作:

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

(all [])
; => true
(all [nil (/ 1 0)])    
; => false
© www.soinside.com 2019 - 2024. All rights reserved.