Как удалить символ Null в таблице в Mathematica?

Мне нужно использовать If внутри цикла Table, например. Table[If[i< 3, i], {i, 5}] даст {1, 2, Null, Null, Null}

Но я хочу, чтобы результат был {1,2}.

Любое исправление для этого?

EDIT:
Что, если мы рассмотрим Table[If[i< 3, f[i]], {i, 5}], который дает {f[1], f[2], Null, Null, Null}

Ответ 1

Лаконично:

Table[If[i < 3, i, ## &[]], {i, 5}]

Это работает, потому что функция ## & не сразу оценивает.

## & является "исчезающей" функцией.

{1, 2, ## &[], 3, 4}
----> {1, 2, 3, 4}

Подробнее см. SlotSequence.

Ответ 2

Если вам нужно удалить его из существующего списка, вы можете использовать

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:

[email protected][If[i < 3, Sow[i]], {i, 5}]
list = %[[2, 1]]

Я фактически не проверял использование памяти по сравнению с простым Table и замечаю, что если вы генерируете только числа, которые могут быть сохранены в упакованный массив, конструкция Table может быть более эффективной с точки зрения памяти. С другой стороны, если вы создадите действительно огромное количество генерических выражений, большинство из которых будет отклонено в If, Sow/Reap может быть лучше.

Ответ 3

В качестве альтернативы вы можете использовать вариант Table от этого ответа, который был разработан специально для условного построения таблиц. Вот как это будет выглядеть:

In[12]:= tableGenAltMD[i,{i,5},#<3&]
Out[12]= {1,2}

Последний аргумент - это функция, представляющая условие. На самом деле было бы неплохо также иметь синтаксис, где можно было бы использовать i (и/или другие переменные итератора) напрямую, и такой синтаксис, вероятно, не сложно добавить.

Ответ 4

Если вы используете Sequence [] вместо Null, вы можете сделать

Table[If[i < 3, i, Hold[Sequence[]]] // ReleaseHold, {i, 5}]

Я долгое время хотел, чтобы If имел бы Attribute SequenceHold. Я думаю, что однажды предложил это WRI, но есть, вероятно, (хорошие?) причины для того, чтобы не шляпа этого атрибут. Можно попробовать, если кто-то посмеет изменить встроенные символы (чего, вероятно, не следует делать):

Unprotect[If];
SetAttributes[If, SequenceHold];

Тогда Последовательность [] в If будет работать:

Table[If[i < 3, i, Sequence[]], {i, 5}]

Ответ 5

В предыдущем anwser часть ## &[] может быть заменена встроенным символом Nothing

Table[If[i < 3, i, Nothing], {i, 5}]

дает

{1, 2}