Только надо учитывать, что это ассоциативный хэш, а не массив, и поэтому доступ по индексу выполняется в несколько раз медленнее.
Чем где? В PHP любой массив всегда ассоциативный, что ты с ним ни делай.
Впрочем, они их хорошо оптимизировали, потому производительность – далеко не главная проблема такого архитектурного решения.
И говоря, что конструкцию вида «for i in range(len(seq)):» не стоит использовать, нужно уточнять, что это касается исключительно ситуаций итерирования обьекта. Для имитации же именно поведения for эта конструкция вполне легальна.
Я не спорю, и статья явно направлена на тех, кто совсем не в курсе и допускает довольно серьёзные неточности.
с названием одного, а механикой другого.
Моя же позиция в том, что название for часто используется и для другой механики во многих языках.
Например, в Rust, Kotlin, Julia, Nim, Zig.
Строго говоря в питоне вообще нет «for» — есть только «foreach». И инкремента индекса (как и самого индекса) тоже нет — есть проход по списку, сгенерированому функцией range() или поданому явно.
Что я и сказал, да.
Строго говоря в питоне вообще нет «for» — есть только «foreach».
Касательно терминологии, есть множество языков, где for выступает именно как оператор обхода по итератору (условно).
Самый яркий пример – Raku, потому что там есть for @scores.kv -> $i, $score { и есть loop (my $i = 0; $i < @scores.elems; ++$i) {.
С++ обычно не рассматривается в отрыве от С, так как является его надмножеством, а в С вполне есть старый добрый «for» без всяких последовательностей.
и то что в питоне их обьединили в одно не ставит между ними знак равенства
Это не совсем так, for в Python только один, и для инкремента числа используется тот же самый обход последовательности, генерируемой функцией range.
Вот где действительно объединены, так это в C++, Java, JavaScript и (частично) в Perl5.
имея опыт работы с другим популярным языком программирования, вроде PHP или JavaScript, то вам знакома методика применения переменной-счётчика, хранящей, например, индекс текущего элемента массива, обрабатываемого в цикле.
Банальнейшая вещь и с незапамятных времён.
Но это, конечно же, не совсем enumerate, ведь вместо инкремента тут ключи ассоциативного массива (в данном случае не отличающиеся).
Некоторое время назад тоже приметил, что проблема 2038 года присутствует в сих функциях, потому просто решил не связываться, ведь можно и самому посчитать количество секунд с начала UNIX-эпохи:
SELECT timestampdiff(SECOND, DATE '1970-01-01', DATE '2038-01-20');
SELECT DATE '1970-01-01' + INTERVAL '2147558400' SECOND;
Если нужна дробная часть, то уже всё далеко не так приятно, но ничего невозможного:
SELECT timestampdiff(SECOND, DATE '1970-01-01', TIMESTAMP '2038-01-20 00:00:00.123090') + microsecond(TIMESTAMP '2038-01-20 00:00:00.123090') / 1000000;
SELECT DATE '1970-01-01' + INTERVAL '2147558400.123090' SECOND_MICROSECOND;
Вне цикла подобные манипуляции вообще ничего не значат на общем фоне. Так-то их можно вообще вынести наружу… только зачем?
плюс строгое равенство при сравнении одиночных символов
При сравнении строк иначе и нельзя. А вот при сравнении (гарантированных) чисел никакой разницы тут не будет.
Не говоря уже про UTF-8
Все версии сделаны именно так, чтобы сравнивались именно индивидуальные байты для однородности и простоты (ну, в большинстве случаев).
Но вообще, как ни иронично, именно вариант с конвертацией в массив чисел более юникододружелюбный, потому что с ним для UTF-8 нужно просто заменить ord на mb_ord, а иначе нужно использовать mb_substr; а это, сам понимаешь, уже целый вызов функции внутри цикла.
Да, квадратные скобки как замена
array()
появились в PHP 5.4, но вовсе не в этом суть.Ну хорошо, вот, это будет работать хоть на PHP 4:
Чем где? В PHP любой массив всегда ассоциативный, что ты с ним ни делай.
Впрочем, они их хорошо оптимизировали, потому производительность – далеко не главная проблема такого архитектурного решения.
"Жулик" тут совсем не к месту. Может, "самозванец" или перефразировать с "некомпетентный"…
Рискуя быть занудой:
Очевидно, нужно перейти на Chromium, чтобы растерять вообще всех пользователей, как это сделала Opera. Так победим.
Если читающее сейчас мой комментарий создание в 10 000-м году или позже и использует MariaDB или MySQL, то… да что с вами не так %)?
Иллюстрация идентичности:
Я не спорю, и статья явно направлена на тех, кто совсем не в курсе и допускает довольно серьёзные неточности.
Моя же позиция в том, что название
for
часто используется и для другой механики во многих языках.Например, в Rust, Kotlin, Julia, Nim, Zig.
Что я и сказал, да.
Касательно терминологии, есть множество языков, где
for
выступает именно как оператор обхода по итератору (условно).Самый яркий пример – Raku, потому что там есть
for @scores.kv -> $i, $score {
и естьloop (my $i = 0; $i < @scores.elems; ++$i) {
.Почему же не рассматривается? Рассматривается.
Особенно когда обсуждаются специфичные для C++ особенности.
Я имею в виду, что оператор
for
используется для обоих вариантов цикла в C++. В C, естественно – нет.Это не совсем так,
for
в Python только один, и для инкремента числа используется тот же самый обход последовательности, генерируемой функциейrange
.Вот где действительно объединены, так это в C++, Java, JavaScript и (частично) в Perl5.
Есть такой длинный и уродливый:
Лучше уж в две строки.
В PHP самым стандартным является такой подход:
Банальнейшая вещь и с незапамятных времён.
Но это, конечно же, не совсем
enumerate
, ведь вместо инкремента тут ключи ассоциативного массива (в данном случае не отличающиеся).А вот сие уже гарантированно эквивалентно:
Сам
enumerate
тоже можно переизобрести, если очень хочется:Либо с
yield
(медленнее при использовании с массивами (PHP 7.4)):Ещё при необходимости дробной части можно получить количество секунд так:
Так дробная часть сохраняет количество знаков.
К сожалению, всё равно нужно указывать datetime дважды.
Некоторое время назад тоже приметил, что проблема 2038 года присутствует в сих функциях, потому просто решил не связываться, ведь можно и самому посчитать количество секунд с начала UNIX-эпохи:
Если нужна дробная часть, то уже всё далеко не так приятно, но ничего невозможного:
Как бы,
ord
…Неужели так сложно поверить, что числа сравнивать дешевле, чем целые строки, хоть и единичные %)?
Два
for
на 40 000 циклов суммарно.А вот сравнение происходит 400 000 000 раз.
Вне цикла подобные манипуляции вообще ничего не значат на общем фоне. Так-то их можно вообще вынести наружу… только зачем?
При сравнении строк иначе и нельзя. А вот при сравнении (гарантированных) чисел никакой разницы тут не будет.
Все версии сделаны именно так, чтобы сравнивались именно индивидуальные байты для однородности и простоты (ну, в большинстве случаев).
Но вообще, как ни иронично, именно вариант с конвертацией в массив чисел более юникододружелюбный, потому что с ним для UTF-8 нужно просто заменить
ord
наmb_ord
, а иначе нужно использоватьmb_substr
; а это, сам понимаешь, уже целый вызов функции внутри цикла.Сравнение чисел просто немножко дешевле.
А, и правда.
Таки тем, что это C#7 без особой на то причины (а там замер с Mono 5).