我需要在Table
循环中使用If
语句,例如Table[If[i< 3, i], {i, 5}]
将返回{1, 2, Null, Null, Null}
但我希望结果是{1,2}
。
有什么解决方法吗?
编辑:
如果我们考虑Table[If[i< 3, f[i]], {i, 5}]
,它将返回{f[1], f[2], Null, Null, Null}
我需要在Table
循环中使用If
语句,例如Table[If[i< 3, i], {i, 5}]
将返回{1, 2, Null, Null, Null}
但我希望结果是{1,2}
。
有什么解决方法吗?
编辑:
如果我们考虑Table[If[i< 3, f[i]], {i, 5}]
,它将返回{f[1], f[2], Null, Null, Null}
简洁地说:
Table[If[i < 3, i, ## &[]], {i, 5}]
这个方法有效是因为函数 ## &
不会立即执行。
## &
是一种“消失”的函数。
{1, 2, ## &[], 3, 4}
----> {1, 2, 3, 4}
请参阅SlotSequence,以了解更多信息。
Sequence@@{}
,它不太优雅(也许稍微慢一点)。 - Leonid ShifrinIf
内部使用 Unevaluated @ Sequence []
。 (顺便问一句,你知道除了谷歌以外如何搜索评论吗?我想找到那个交流。) - Mr.Wizard如果你需要从现有列表中删除它,可以使用
DeleteCases[list, Null]
或者list /. Null -> Sequence[]
(稍微高级一些)。
关于你上面的Table
示例,首先请注意,If
中的第二个逗号是不必要的(甚至会被标为粉色):
list = Table[If[i < 3, i], {i, 5}]
要根据条件筛选表格元素,您可能需要使用类似于以下内容的东西
list = Select[Table[i, {i, 5}], # < 3 &]
最后,如果你需要生成一个列表但不想将被拒绝的元素添加到其中(以节省内存),我建议使用Reap
和Sow
:
Reap@Do[If[i < 3, Sow[i]], {i, 5}]
list = %[[2, 1]]
我并没有实际验证过这种方法与普通的Table
相比所使用的内存量,但是需要注意的是,如果你只生成可以存储在打包数组中的数字,那么Table
结构可能更加内存高效。另一方面,如果你生成了大量的通用表达式,其中大多数将被If
拒绝,那么Sow
/Reap
可能更好。
Reap-Sow
,在我的答案中(只是条件语法可能更友好)。 - Leonid Shifrin作为替代方案,您可以使用此答案中的Table
变体,该变体专门设计用于条件表格构建。下面是它的外观:
In[12]:= tableGenAltMD[i,{i,5},#<3&]
Out[12]= {1,2}
i
(和/或其他迭代器变量)也很好,这样的语法可能不难添加。Cases
,而有人给您提供了一个(在顶层实现),您不会使用它吗(如果实现正确)?很多时候这只是习惯、约定等问题。 - Leonid Shifrin## &[]
可以替换为内置符号 Nothing
。Table[If[i < 3, i, Nothing], {i, 5}]
提供
{1, 2}
Table[If[i < 3, i, Hold[Sequence[]]] // ReleaseHold, {i, 5}]
我很长一段时间都希望 If 有一个属性 SequenceHold。我想我曾经向WRI建议过这个想法,但是可能有(好?)理由使得If没有这个属性。 如果敢于更改内置符号(应该不应该这样做),可以尝试:
Unprotect[If];
SetAttributes[If, SequenceHold];
那么在If语句中,Sequence[]只会起作用:
Table[If[i < 3, i, Sequence[]], {i, 5}]