Функция alloca велика, и все скептики просто распространяют FUD.
void foo()
{
int x = 50000;
char array[x];
char *parray = (char *)alloca(x);
}
Массив и парсер являются ТОЧНО одинаковыми с ТОЧНО теми же рисками. Говорить одно лучше другого - это синтаксический выбор, а не технический.
Что касается выбора переменных стека против переменных кучи, существует много преимуществ для долгосрочных программ, использующих стек над кучей для переменных с время жизни. Вы избегаете фрагментации кучи, и вы можете избежать роста пространства процесса с неиспользуемым (непригодным) кучевым пространством. Вам не нужно его чистить. Вы можете контролировать распределение стека в процессе.
Почему это плохо?
Или индексирование списка:
print([[val * 2 for val in range(0, N // 2)],[0]][N<2])
Или dict.get
:
print({0:[val * 2 for val in range(0, N // 2)],1:[0]}.get(N<2))
Оба воспроизводят ожидаемый результат.
1 // 2 равно 0, поэтому у вас есть диапазон (0, 0), который является пустым списком, поэтому часть карты для понимания списка не выполняется вообще.
Если вы хотите получить [0] для N < 2, вы, вероятно, хотите сделать это следующим образом:
[val*2 for val in range(0,N//2)] if N<2 else [0]
Если N = 1
, то N//2 = 0
. Таким образом, ваш цикл for не выполняется, так как это будет диапазон от 0 до 0. Вы можете сделать [val * 2 for val in range(0, N // 2)] if N >= 2 else [0]
Вот как ваше выражение читается с точки зрения компьютера.
[(0 if N < 2 else val * 2) for val in range(0, N // 2)]
Таким образом, бит for
происходит первым. И если N
меньше, чем 2
, то range(0, N // 2)
пусто, поэтому бит 0 if N < 2 else val * 2
фактически никогда не выполняется.
В вашем случае, было бы более разумно просто иметь два разных случая.
if N < 2:
return [0]
else:
return [val * 2 for val in range(0, N // 2)]
Или, если хотите, в одну строку,
[0] if N < 2 else [val * 2 for val in range(0, N // 2)]
это работает для меня. попробуйте следующее:
N = 3
a = [0 if N<2 else val*2 for val in range(0,N//2)]
#output: [0]