有没有任何有效的简单方法可以使用 Mathematica 比较两个具有相同长度的列表?
给定两个列表 A={a1,a2,a3,...an}
和 B={b1,b2,b3,...bn}
,我会说A>=B
当且仅当全部ai>=bi
。
有两个列表的内置逻辑比较,A==B
,但没有A>B
。 我们是否需要像这样比较每个元素
And@@Table[A[[i]]>=B[[i]],{i,n}]
有更好的技巧吗?
编辑: 非常感谢大家。
这里还有一个问题:
如何在 N 个列表中找到最大列表(如果存在)?
Given two lists A={a1,a2,a3,...an}
and B={b1,b2,b3,...bn}
, I would say A>=B
if and only if all ai>=bi
.
There is a built-in logical comparison of two lists, A==B
, but no A>B
.
Do we need to compare each element like this
And@@Table[A[[i]]>=B[[i]],{i,n}]
Any better tricks to do this?
EDIT:
Great thanks for all of you.
Here's a further question:
How to find the Maximum list (if exist) among N lists?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
方法1:我更喜欢这种方法。
方法2:这只是为了好玩。正如 Leonid 指出的那样,对于我使用的数据来说,它被赋予了一些不公平的优势。
如果进行两两比较,并在适当的时候返回 False 和 Break,
那么循环可能会更有效(尽管我通常在 mma 中避免循环):
对 10^6 数字列表的一些计时比较:
编辑:我删除了方法 #2 的计时,因为它们可能会产生误导。方法#1 更适合作为通用方法。
Method 1: I prefer this method.
Method 2: This is just for fun. As Leonid noted, it is given a bit of an unfair advantage for the data I used.
If one makes pairwise comparisons, and return False and Break when appropriate,
then a loop may be more efficient (although I generally shun loops in mma):
Some timing comparisons on lists of 10^6 numbers:
Edit: I removed the timings for my Method #2, as they can be misleading. And Method #1 is more suitable as a general approach.
例如,
应该做的工作。
编辑:另一方面,这
快了 20 倍。不过也丑了20倍。
编辑 2:由于 David 没有可用的 C 编译器,这里是所有计时结果,有两个差异。首先,他的第二种方法已被修复以比较所有元素。其次,我将
a
与其自身进行比较,这是最坏的情况(否则,我上面的第二种方法只需比较第一个元素之前的元素即可违反条件)。所以编译的方法要快很多(注意David的第二种方法和这里编译的方法是同一个算法,唯一的区别是开销)。
所有这些都是使用电池供电,因此可能会有一些随机波动,但我认为它们具有代表性。
编辑3:如果,正如 ruebenko 在评论中建议的那样,我用
Compile`GetElement
替换Part
,就像这样,那么
cmp2
的速度是原来的两倍作为cmp
。For instance,
should do the job.
EDIT: On the other hand, this
is 20 times faster. 20 times uglier, too, though.
EDIT 2: Since David does not have a C compiler available, here are all the timing results, with two differences. Firstly, his second method has been fixed to compare all elements. Secondly, I compare
a
to itself, which is the worst case (otherwise, my second method above will only have to compare elements up to the first to violate the condition).So the compiled method is much faster (note that David's second method and the compiled method here are the same algorithm, and the only difference is overhead).
All these are on battery power so there may be some random fluctuations, but I think they are representative.
EDIT 3: If, as ruebenko suggested in a comment, I replace
Part
withCompile`GetElement
, like thisthen
cmp2
is a twice as fast ascmp
.由于您在问题中提到效率是一个因素,您可能会发现这些函数很有用:
这些函数将相当高效。 @David 的解决方案仍然快两到四倍,如果您想要极快的速度并且您的列表是数字(由整数或实数组成),您可能应该使用 C 编译(@acl 的解决方案以及类似的其他解决方案)运营商)。
您可以使用相同的技术(使用
Unitize
而不是UnitStep
来实现equal
和unequal
)来实现其他比较运算符(>
、<
、==
、!=
)。请记住UnitStep[0]==1
。Since you mentioned efficiency as a factor in your question, you may find these functions useful:
These functions will be reasonably efficient. The solution of @David is still two-four times faster, and if you want extreme speed and your lists are numerical (made of Integer or Real numbers), you should probably use compilation to C (the solution of @acl and similarly for other operators).
You can use the same techniques (using
Unitize
instead ofUnitStep
to implementequal
andunequal
), to implement other comparison operators (>
,<
,==
,!=
). Keep in mind thatUnitStep[0]==1
.像
Greater、GreaterEqual、Equal、Less、LessEqual
这样的比较函数可以通过多种方式应用于列表(它们都是问题中方法的变体)。对于两个列表:
以及两个带有数字条目的实例,
您可以使用
带有符号条目的列表
给出
对于一般比较,可以创建一个通用比较函数,例如
使用 as
给出
True
。对于符号条目,给出逻辑上等价的表达式
a1 <= b1 && a2 <= b2 && a3 <= b3
。Comparison functions like
Greater, GreaterEqual, Equal, Less, LessEqual
can be made to apply to lists in a number of ways (they are all variations of the approach in your question).With two lists:
and two instances with numeric entries
you can use
With lists with symoblic entries
gives
For general comparisons, one can create a general comparison function like
Using as
gives
True
. With symbolic entriesgives the logially equivalent expression
a1 <= b1 && a2 <= b2 && a3 <= b3
.当使用压缩数组和数字比较器(例如
>=
)时,很难击败 David 的方法 #1。然而,对于无法转换为简单算术的更复杂的测试,需要另一种方法。
一个好的通用方法,特别是对于解包列表,是使用
Inner
:这不会提前进行所有比较,因此在某些情况下比
And @ 更有效@MapThread[测试,{a,b}]
。这说明了差异:如果数组是打包的,特别是如果返回
False
的可能性很高,那么诸如 David 的方法 #2 之类的循环是一个不错的选择。可能这样写会更好:When working with packed arrays and numeric comparator such as
>=
it would be hard to beat David's Method #1.However, for more complicated tests that cannot be converted to simple arithmetic another method is required.
A good general method, especially for unpacked lists, is to use
Inner
:This does not make all of the comparisons ahead of time and can therefore be much more efficient in some cases than e.g.
And @@ MapThread[test, {a, b}]
. This illustrates the difference:If the arrays are packed and especially if the likelihood that the return is
False
is high then a loop such as David's Method #2 is a good option. It may be better written: