Как удалить нулевой символ в таблице в Mathematica? - PullRequest
10 голосов
/ 16 января 2012

Мне нужно использовать 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}

Ответы [ 5 ]

29 голосов
/ 16 января 2012

Лаконично:

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

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

## & - это «исчезающая» функция.

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

См. SlotSequence для получения дополнительной информации.

14 голосов
/ 16 января 2012

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

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 может быть лучше.

6 голосов
/ 16 января 2012

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

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

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

3 голосов
/ 16 января 2012

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

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

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

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

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

Table[If[i < 3, i, Sequence[]], {i, 5}]
1 голос
/ 08 марта 2016

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

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

дает

{1, 2}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...