如何对mathematica中的所有列表元素进行逻辑测试

9 wolfram-mathematica

我有一个列表,我想对每个元素应用逻辑测试,如果其中任何一个元素不满足这个条件,则返回false.我想在Mathematica中写这个或找到一个内置函数,但似乎ForAll并没有真正做到这一点.

我的问题是:如何最有效地做到这一点?

额外:Exists功能类似如何:即如果列表中有任何元素满足条件,则返回true.

nix*_*gle 9

您问题的第一部分的答案可能是这样的:

forAll[list_, cond_] := Select[list, ! cond@# &, 1] === {};
Run Code Online (Sandbox Code Playgroud)

这是这样使用的:

forAll[{1, 2, 3, 3.5}, IntegerQ]
Run Code Online (Sandbox Code Playgroud)

"存在"功能已经原生实现为MemberQ.它可以重新实现为:

exists[list_,cond_] := Select[list, cond, 1] =!= {};
Run Code Online (Sandbox Code Playgroud)

像它一样使用它

exists[Range@100, (10 == # &)]
Run Code Online (Sandbox Code Playgroud)

返回true,因为10是导致Select返回的元素{10},它不等于{}.


Ver*_*eia 8

这个答案并不是为了展示最有效的方法,而是为了在Mathematica中展示一些重要核心功能的教学目的而提供的替代方法.

nixeagle的答案避免显式测试列表中的每个元素.如果测试不适合包含在第三个参数中Select,那么下面的内容可能会有用.

为此,您需要了解标准OrAnd函数,以及Map(/@)Apply(@@)命令,这些对于任何Mathematica用户来说都非常重要.(见本教程)

这是一个简单的例子.

In[2]:= data = RandomInteger[{0, 10}, {10}]

Out[2]= {10, 1, 0, 10, 1, 5, 2, 2, 4, 1}

In[4]:= # > 5 & /@ data

Out[4]= {True, False, False, True, False, False, False, False, False, \
False}

In[6]:= And @@ (# > 5 & /@ data)

Out[6]= False
Run Code Online (Sandbox Code Playgroud)

这里发生的是你使用函数("大于5")映射到列表的每个元素Map,以获得真/假值列表.然后,您将标准逻辑函数And应用于整个列表以获取单个布尔值.

这些都是Mathematica中的核心功能,我建议您仔细阅读这些功能的文档并练习使用它们.

这不是最有效的方法,但对于小问题,您不会注意到差异.

In[11]:= Do[Select[data, ! # > 5 &, 1] === {}, {10000}] // Timing

Out[11]= {0.031, Null}

In[12]:= Do[And @@ (# > 5 & /@ data);, {10000}] // Timing

Out[12]= {0.11, Null}
Run Code Online (Sandbox Code Playgroud)

对于Exists中,替代Select将是MatchQ的模式或MemberQ显式值.该文档有一些有用的例子.