Массив с конца: ~n

Чудесное нашлось в комментариях на «Хабре»: логичный, на мой взгляд, способ получать значения с конца массива. Способ, вообще говоря, для «Пайтона», но и для «ПХП» можно применить.

В «Пайтоне» есть такая проблема, даже не то чтобы проблема, скорее мелкое неудобство, что списки, если их считать с начала, нумеруются с нуля, а если с конца — с минус единицы:
>>> print([1,2,3][0], [3,2,1][-1])
(1, 1)
Лично я к этому так привык, что в нелогичность такого поведения сразу и не вник. Неудобство становится более очевидным, если от фиксированных значений перейти к переменным:
>>> i=2
>>> print([1,2,3,4][i], [4,3,2,1][-i-1])
(3, 3)
Чтобы брать значения с конца, везде, как приклееную, приходится таскать эту дурацкую минус единицу. Но есть способ лучше, более того, я им иногда пользовался, но почему-то не возвёл в систему — можно использовать тильду. Всё сразу становится более логичным:
>>> i=2
>>> print([1,2,3,4][i], [4,3,2,1][~i])
(3, 3)
>>> print([1,2,3][0], [3,2,1][~0])
(1, 1)
Для тех, кто не понимает смысла операции «тильда» можно объяснить, что без тильды значения берутся с начала, с тильдой — с конца. Здо́рово!

Обычно в таких случаях возражают, что новички будут путаться. Это какой-то странный аргумент, честное слово, в «Пайтоне» для новичков очень много новых «значков» — те же декораторы, а «тильда» есть в большинстве распространённых языков, пусть новички учатся, к тому же забыть вычесть единицу — одна из частых ошибок, встречается не только у новичков, но и у матёрых программистов.
4 января 2014 20:27

zg (zg.livejournal.com)
5 января 2014, 00:16

справедливо для платформ, на которых отрицательные числа представлены в дополнительном коде.

Евгений Степанищев (bolknote.ru)
5 января 2014, 06:03, ответ предназначен zg (zg.livejournal.com):

Я, кстати, других платформ и не видел, они бывают?

В любом случае, «Пайтону» до низкого уровня дела нет. Тильда там реализует оператор «NOT», который по определению обязан работать как NOT(n)=-n-1, вот и документация «Пайтона» говорит о том же (http://docs.python.org/2/reference/expressions.html#unary-arithmetic-and-bitwise-operations):
The unary ~ (invert) operator yields the bitwise inversion of its plain or long integer argument. The bitwise inversion of x is defined as -(x+1). It only applies to integral numbers.

zg (zg.livejournal.com)
5 января 2014, 17:31, ответ предназначен Евгений Степанищев (bolknote.ru):

Я, кстати, других платформ и не видел, они бывают?
бывают: http://www.unisys.com/unisys/theme/index.jsp?id=1120000970018010225&pid=16000034
который по определению обязан работать как NOT(n)=-n-1
ну тогда да, питон может быть только на архитектурах с дополнительным кодом.

Станислав (инкогнито)
6 января 2014, 06:36

Спасибо, я как раз такой новичок. Частенько забывал про "минус единицу" в примерах с переменной.

vasa_c (инкогнито)
6 января 2014, 12:42

У меня в этом шрифте тильда, как минус показывается.
Так что разницу в примерах, только скопировав увидел :)

Евгений Степанищев (bolknote.ru)
6 января 2014, 13:13, ответ предназначен vasa_c

А что за шрифт выбрался такой неразборчивый?

vasa_c (инкогнито)
6 января 2014, 13:24, ответ предназначен Евгений Степанищев (bolknote.ru):

В стилях "11px Monaco,'Trebuchet MS',Tahoma,sans-serif"
У меня, видимо, Trebuchet срабатывает.
Firefox, Убунта.

Евгений Степанищев (bolknote.ru)
6 января 2014, 17:01, ответ предназначен vasa_c

А что в Линуксе есть из этой шрифтовой семьи, что выглядит хорошо?

Kildor (kildor.ya.ru)
7 января 2014, 07:01, ответ предназначен Евгений Степанищев (bolknote.ru):

DejaVu Sans? Хотя бы просто, поменять местами Требушет и тахому. Или выкинуть его нафиг, пускай браузер сам гротески подставляет.

Евгений Степанищев (bolknote.ru)
7 января 2014, 19:03, ответ предназначен Kildor (kildor.ya.ru):

Поменять не могу. Требушет ЭмЭс отлично смотрится на Винде, а Тахома его перебьёт — на Винде она тоже есть. А ДеджаВю Санс на всех Линуксах есть?

Kildor (kildor.ya.ru)
9 января 2014, 08:01, ответ предназначен Евгений Степанищев (bolknote.ru):

Тады ой ;)

Из википедии:
Некоторые дистрибутивы GNU/Linux (Ubuntu, OpenSUSE, Mandriva Linux) поставляются по умолчанию со шрифтами DejaVu. Также эти шрифты включаются в установочные пакеты OpenOffice.org.
В зависимостях к LibreOffice они тоже есть. И я не могу себе представить десктопного линукса в котором бы не было офиса (опен или либры).

Евгений Степанищев (bolknote.ru)
9 января 2014, 08:37, ответ предназначен Kildor (kildor.ya.ru):

Воткнул перед всеми шрифтами :)

Kildor (kildor.ya.ru)
9 января 2014, 11:52, ответ предназначен Евгений Степанищев (bolknote.ru):

Ещё в одном месте (собственно в блоках кода):
pre code {
  font: 11px Monaco, 'Trebuchet MS', Tahoma, sans-serif;
}

Евгений Степанищев (bolknote.ru)
9 января 2014, 14:18, ответ предназначен Kildor (kildor.ya.ru):

Готово!

leoleo2(новичок в Python) (инкогнито)
12 января 2014, 17:14

По поводу нелогичности записи.

Для меня, например, вполне логично индекс с конца считать, как короткую запись "len(s)-1".
Для тех кто на чём-то си-подобном писал, это очевидная мнемоника, вроде-бы. Или нет? :)

Хотя, конечно, все фломастеры разные на вкус и фокус радует :)

Евгений Степанищев (bolknote.ru)
12 января 2014, 22:14, ответ предназначен leoleo2(новичку в Python)

Логичная или нет, люди всё-таки часто путаются. А с такой записью, глядишь, перестанут.

Максим (инкогнито)
6 февраля 2014, 13:31

Лично меня подобная запись заставила бы сбиться с «чтения» и залипнуть; на таком высоком уровне языка ждешь, что битовые операции используются только когда биты и интересуют (двоичный формат разбираем, или конечный автомат какой-нибудь).

Евгений Степанищев (bolknote.ru)
7 февраля 2014, 08:06, ответ предназначен Максиму

Ну больше не ждите, тоже мне проблема.

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)