Ответ 1
Лаконично:
Table[If[i < 3, i, ## &[]], {i, 5}]
Это работает, потому что функция ## &
не сразу оценивает.
## &
является "исчезающей" функцией.
{1, 2, ## &[], 3, 4}
----> {1, 2, 3, 4}
Подробнее см. SlotSequence.
Мне нужно использовать 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}
Лаконично:
Table[If[i < 3, i, ## &[]], {i, 5}]
Это работает, потому что функция ## &
не сразу оценивает.
## &
является "исчезающей" функцией.
{1, 2, ## &[], 3, 4}
----> {1, 2, 3, 4}
Подробнее см. SlotSequence.
Если вам нужно удалить его из существующего списка, вы можете использовать
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
может быть лучше.
В качестве альтернативы вы можете использовать вариант Table
от этого ответа, который был разработан специально для условного построения таблиц. Вот как это будет выглядеть:
In[12]:= tableGenAltMD[i,{i,5},#<3&]
Out[12]= {1,2}
Последний аргумент - это функция, представляющая условие. На самом деле было бы неплохо также иметь синтаксис, где можно было бы использовать i
(и/или другие переменные итератора) напрямую, и такой синтаксис, вероятно, не сложно добавить.
Если вы используете 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}]
В предыдущем anwser часть ## &[]
может быть заменена встроенным символом Nothing
Table[If[i < 3, i, Nothing], {i, 5}]
дает
{1, 2}