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

时间:2022-05-20 20:31:03

Are there built in functions in Clojure similar to Python's any and all functions?

Clojure中是否有内置函数,类似于Python的所有函数?

For example, in Python, it's all([True, 1, 'non-empty string']) == True.

例如,在Python中,它是全部([True,1,'非空字符串'])== True。

2 个解决方案

#1


41  

(every? f data) [docs] is the same as all(f(x) for x in data).

(每个?f数据)[docs]与all(数据中x的f(x))相同。

(some f data) [docs] is like any(f(x) for x in data) except that it returns the value of f(x) (which must be truthy), instead of just true.

(一些f数据)[docs]就像任何(数据中的x的f(x)),除了它返回f(x)的值(必须是真实的),而不仅仅是真。

If you want the exact same behaviour as in Python, you can use the identity function, which will just return its argument (equivalent to (fn [x] x)).

如果你想要与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

#2


3  

In clojure and and or are quite similar to python's all and any, with the caveat that (just like clojure.core/some) they return the element that will satifsy it... thus you can use it together with boolean to convert it

在clojure中和/或者与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

I use boolean instead of true? since the latter will return true iff the argument is the value true... so boolean is more akin to python's bool in that it evaluates the truthyness

我用boolean而不是true?因为后者将返回true如果参数是值true ...所以布尔值更类似于python的bool,因为它评估了真实性

Unlike some & every?, and & or are macros, so if you always want to convert the result to a boolean, you cannot simply do (def any (comp boolean or)) but you have to define a macro like

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

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

a side-effect/advantage of being macros, is that they are lazy/can shortcircuit (just like python's and & or, that are infix binary operators however)

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

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

and they're just like python's any and all, even when called without arguments

它们就像python一样,即使在没有参数的情况下被调用也是如此

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

in python:

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

If you prefer to have to call any/all with a single list/sequence argument, you can simply do:

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

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

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

#1


41  

(every? f data) [docs] is the same as all(f(x) for x in data).

(每个?f数据)[docs]与all(数据中x的f(x))相同。

(some f data) [docs] is like any(f(x) for x in data) except that it returns the value of f(x) (which must be truthy), instead of just true.

(一些f数据)[docs]就像任何(数据中的x的f(x)),除了它返回f(x)的值(必须是真实的),而不仅仅是真。

If you want the exact same behaviour as in Python, you can use the identity function, which will just return its argument (equivalent to (fn [x] x)).

如果你想要与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

#2


3  

In clojure and and or are quite similar to python's all and any, with the caveat that (just like clojure.core/some) they return the element that will satifsy it... thus you can use it together with boolean to convert it

在clojure中和/或者与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

I use boolean instead of true? since the latter will return true iff the argument is the value true... so boolean is more akin to python's bool in that it evaluates the truthyness

我用boolean而不是true?因为后者将返回true如果参数是值true ...所以布尔值更类似于python的bool,因为它评估了真实性

Unlike some & every?, and & or are macros, so if you always want to convert the result to a boolean, you cannot simply do (def any (comp boolean or)) but you have to define a macro like

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

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

a side-effect/advantage of being macros, is that they are lazy/can shortcircuit (just like python's and & or, that are infix binary operators however)

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

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

and they're just like python's any and all, even when called without arguments

它们就像python一样,即使在没有参数的情况下被调用也是如此

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

in python:

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

If you prefer to have to call any/all with a single list/sequence argument, you can simply do:

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

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

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