Почему в Python работает вставка пути после окончания списка? [Дубликат]

Если то, что вы пытаетесь сделать, это позволить пользователям добавлять закладки / обмениваться страницами, и вам не нужно, чтобы это был именно правильный 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);  }  

Надеюсь, это имеет смысл! Это полезный подход для некоторых ситуаций.

19
задан Harish Kayarohanam 16 September 2014 в 04:09
поделиться

7 ответов

Вместо того, чтобы противопоставлять вставку к назначению элемента, она более аналогична назначению slice, так как оба изменяют размер списка.

>>> a = [1, 2, 3]
>>> a[100:100] = [100]
>>> a
[1, 2, 3, 100]

Срезки также не повышают IndexError, и это согласуется с :

a.insert(100, 100)
0
ответ дан A. Coady 16 August 2018 в 04:19
поделиться

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) как удобный способ убедиться, что вы всегда вводите число, большее, чем длина списка.

3
ответ дан agconti 16 August 2018 в 04:19
поделиться

Из docs :

list.insert (i, x) Вставить элемент в заданную позицию. Первый аргумент - это индекс элемента, перед которым нужно вставить, поэтому a.insert (0, x) вставлен в начале списка, а a.insert (len (a), x) эквивалентен a.append ( x).

Итак, технически, когда вы делаете 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;
}
14
ответ дан dano 16 August 2018 в 04:19
поделиться
  • 1
    Трудная формулировка. Перед! = Сразу. – ApproachingDarknessFish 15 September 2014 в 04:04
  • 2
    @ValekHalfHeart Я согласен, я бы хотел, чтобы документы были более конкретными при описании ожидаемого поведения при вставке с любым возможным индексом (даже с индексом & lt; 0), включая ожидаемые ошибки. – alfasin 15 September 2014 в 04:07
  • 3
    @ApproachingDarknessFish: Это довольно смешно. Нужно ли предполагать, что в некоторой реализации [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.

8
ответ дан Grijesh Chauhan 16 August 2018 в 04:19
поделиться

Комментарии Guido van Rossum, создателя Python, в списке рассылки python-dev (проверьте архивы за сентябрь 2014 года ; по моему опыту, точные URL-адреса для конкретных сообщений имеют способ изменения от время от времени), в ответ на перекрестный вызов OP этого вопроса в этом списке:

В понедельник, 15 сентября 2014 года в 3:46 вечера Марк Лоуренс писал:

Я предполагаю, что он основан на концепциях нарезки. Из документов "s.insert (i, x) - вставляет x в s по индексу, указанному i (так же, как s [i: i] = [x])".

Ах, да. Он соответствует тигам типа s [100:], который является пустой строкой, если s короче 100.

И в другом ответе:

Эта функция имеет существовал с самых ранних дней Python, и даже если бы мы все согласились, что это было неправильно, мы не могли его изменить - это просто сломало бы слишком много существующего кода. Я не могу вспомнить, почему я сделал это таким образом, но это был определенно сознательный выбор; вероятно, какой-то симметрии или кромки. (Обратите внимание, что он тоже работает на другом конце - a.insert (-100, x) будет вставлять x в начале a, если a имеет менее 100 элементов.)

В конечном счете, такое решение является дизайнерским решением. Почти всегда есть конкурирующие проблемы, и вы никогда не сможете найти что-то, что будет интуитивно понятным для всех. Посмотрите, как много разных языков обрабатывают концепцию как фундаментальную, как True и False (на некоторых языках они идентичны числам 1 и 0, а на некоторых языках - ненулевое значение True, а на некоторых языках True и False идентичны characters '1' и '0' (да, действительно!), на некоторых языках они полностью несовместимы с числами или любым другим не строго булевым типом, а на некоторых языках пустые контейнеры False, в другие - это правда, выбор продолжается и продолжается). Или посмотрите на nil / null / None, которые также имеют интересные взаимодействия с булевыми и другими вычислениями. Некоторые языки даже имеют Maybe.

Способ, которым Python обрабатывает вставку списка, удобен в некоторых ситуациях, и достаточно людей считают полезным, что они написали код, который использует и зависит от того, как вставлять себя таким образом. Возможно, документация может быть небольшим яснее, но это действительно не так уж непонятно; и в любом случае, как только вы попробуете его, вы увидите, что он делает, и вы соответственно напишите свой код Python.

2
ответ дан John Y 16 August 2018 в 04:19
поделиться

Когда вы вставляете один элемент в список, длина списка будет возрастать ровно одним - не более, не менее.

1
ответ дан rosuav 16 August 2018 в 04:19
поделиться

Возможно, фактическая реализация прольет некоторый свет.

static int
ins1(PyListObject *self, Py_ssize_t where, PyObject *v)
{
    ...
    if (where > n)
        where = n;
    ...
}

Итак, это отвечает на вопрос о том, как.

Философски, списки не являются массивами , и есть много манипуляций с списками, которые терпимы к странному индексированию. Например, l [1: 1000] вернет [2,3]. Все это предназначено для удобства программиста.

4
ответ дан xavier 16 August 2018 в 04:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: