Если то, что вы пытаетесь сделать, это позволить пользователям добавлять закладки / обмениваться страницами, и вам не нужно, чтобы это был именно правильный URL-адрес, и вы не используете хеш-привязки для чего-либо еще, тогда вы можете сделать это в двух частях; вы используете описанное выше location.hash, а затем реализуете проверку на домашней странице, чтобы искать URL-адрес с хеш-якорем в нем и перенаправлять вас на последующий результат.
Например: [ ! d7]
1) Пользователь находится на www.site.com/section/page/4
2) Пользователь выполняет какое-либо действие, которое изменяет URL-адрес на www.site.com/#/section/page/6
(с хешем). Скажем, что вы загрузили правильный контент для страницы 6 на страницу, поэтому, помимо хэша, пользователь не слишком обеспокоен.
3) Пользователь передает этот URL кому-то другому или заносит в закладки
4) Кто-то другой или тот же пользователь в более поздний срок переходит к www.site.com / # / section / page / 6
5) Код на www.site.com /
перенаправляет пользователя на www.site.com/section/page/6
, используя что-то вроде этого:
if (window.location.hash.length & gt; 0) {window.location = window.location.hash.substring (1); }
Надеюсь, это имеет смысл! Это полезный подход для некоторых ситуаций.
Вместо того, чтобы противопоставлять вставку к назначению элемента, она более аналогична назначению slice, так как оба изменяют размер списка.
>>> a = [1, 2, 3]
>>> a[100:100] = [100]
>>> a
[1, 2, 3, 100]
Срезки также не повышают IndexError, и это согласуется с :
a.insert(100, 100)
a.insert(len(a), x)
является , предположительно действовать так же, как a.append(x)
для попустительства. Посмотрев исходный код метода:
static int
ins1(PyListObject *self, Py_ssize_t where, PyObject *v)
{
Py_ssize_t i, n = Py_SIZE(self);
...
if (where > n)
where = n;
...
}
Вы увидите, что он обрабатывает любой int выше len(a)
таким же образом, устанавливая любой int выше n
- n
.
Следовательно: любой int >= len(a)
будет действовать так же, как list.append(x)
, если он передан как первый аргумент list.insert(i, x)
.
Официальные документы python, вероятно, рекомендуют только len(a)
как удобный способ убедиться, что вы всегда вводите число, большее, чем длина списка.
Из docs :
list.insert (i, x) Вставить элемент в заданную позицию. Первый аргумент - это индекс элемента, перед которым нужно вставить, поэтому a.insert (0, x) вставлен в начале списка, а a.insert (len (a), x) эквивалентен a.append ( x).
blockquote>Итак, технически, когда вы делаете
a.insert(100, 100)
, это гарантирует, что100
будет вставлен в индекс до 100, который, оказывается, в этом случае индекс 3.Далее, мы можем взглянуть на реализацию :
static int ins1(PyListObject *self, Py_ssize_t where, PyObject *v) { Py_ssize_t i, n = Py_SIZE(self); PyObject **items; if (v == NULL) { PyErr_BadInternalCall(); return -1; } if (n == PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "cannot add more objects to list"); return -1; } if (list_resize(self, n+1) == -1) return -1; if (where < 0) { where += n; if (where < 0) where = 0; } if (where > n) // <-- Here the implementation handles indexes > list-len where = n; items = self->ob_item; for (i = n; --i >= where; ) items[i+1] = items[i]; Py_INCREF(v); items[where] = v; return 0; }
[1, 2, 3].insert(2, "foo")
может возникнуть ["foo", 1, 2, 3]
? потому что 0
до 2
... Мне это совсем не нравится. Я тоже ожидал IndexError
, особенно в таком raise
-привычном языке. : /
– Amadan
24 July 2018 в 08:58
В документации написано:
L.insert(index, object) # insert object before index
Так что, когда вы пытаетесь вставить в индекс 100, он действительно получит существующий индекс в списке до 100.
Комментарии Guido van Rossum, создателя Python, в списке рассылки python-dev
(проверьте архивы за сентябрь 2014 года ; по моему опыту, точные URL-адреса для конкретных сообщений имеют способ изменения от время от времени), в ответ на перекрестный вызов OP этого вопроса в этом списке:
В понедельник, 15 сентября 2014 года в 3:46 вечера Марк Лоуренс писал:
Я предполагаю, что он основан на концепциях нарезки. Из документов "s.insert (i, x) - вставляет x в s по индексу, указанному i (так же, как s [i: i] = [x])".
blockquote>Ах, да. Он соответствует тигам типа s [100:], который является пустой строкой, если s короче 100.
blockquote>И в другом ответе:
Эта функция имеет существовал с самых ранних дней Python, и даже если бы мы все согласились, что это было неправильно, мы не могли его изменить - это просто сломало бы слишком много существующего кода. Я не могу вспомнить, почему я сделал это таким образом, но это был определенно сознательный выбор; вероятно, какой-то симметрии или кромки. (Обратите внимание, что он тоже работает на другом конце - a.insert (-100, x) будет вставлять x в начале a, если a имеет менее 100 элементов.)
blockquote>В конечном счете, такое решение является дизайнерским решением. Почти всегда есть конкурирующие проблемы, и вы никогда не сможете найти что-то, что будет интуитивно понятным для всех. Посмотрите, как много разных языков обрабатывают концепцию как фундаментальную, как True и False (на некоторых языках они идентичны числам 1 и 0, а на некоторых языках - ненулевое значение True, а на некоторых языках True и False идентичны characters '1' и '0' (да, действительно!), на некоторых языках они полностью несовместимы с числами или любым другим не строго булевым типом, а на некоторых языках пустые контейнеры False, в другие - это правда, выбор продолжается и продолжается). Или посмотрите на nil / null / None, которые также имеют интересные взаимодействия с булевыми и другими вычислениями. Некоторые языки даже имеют Maybe.
Способ, которым Python обрабатывает вставку списка, удобен в некоторых ситуациях, и достаточно людей считают полезным, что они написали код, который использует и зависит от того, как вставлять себя таким образом. Возможно, документация может быть небольшим яснее, но это действительно не так уж непонятно; и в любом случае, как только вы попробуете его, вы увидите, что он делает, и вы соответственно напишите свой код Python.
Когда вы вставляете один элемент в список, длина списка будет возрастать ровно одним - не более, не менее.
Возможно, фактическая реализация прольет некоторый свет.
static int
ins1(PyListObject *self, Py_ssize_t where, PyObject *v)
{
...
if (where > n)
where = n;
...
}
Итак, это отвечает на вопрос о том, как.
Философски, списки не являются массивами , и есть много манипуляций с списками, которые терпимы к странному индексированию. Например, l [1: 1000] вернет [2,3]. Все это предназначено для удобства программиста.