Тот же адрес не удовлетворял. Определяет инструкции в Python3 [duplicate]

Идиома Python для этого - newList = oldList[:]

22
задан Ashwini Chaudhary 5 October 2014 в 10:36
поделиться

4 ответа

CPython - это сбор мусора, как только они выходят из области видимости, поэтому второй [] создается после сбора первого []. Таким образом, большую часть времени он попадает в ту же ячейку памяти.

Это показывает, что происходит очень четко (выход может отличаться в других реализациях Python):

class A(object):
    def __init__(self): print "a",
    def __del__(self): print "b",

# a a b b False
print A() is A()
# a b a b True
print id(A()) == id(A())
32
ответ дан Glenn Maynard 21 August 2018 в 19:14
поделиться
  • 1
    Хотя ответ Томаса одинаково правильный, вы предоставляете конкретные аргументы, которые я искал. – spenthil 7 October 2010 в 00:05
  • 2
    Итак, почему print id({}); a = []; print id({}) дважды печатает одно и то же значение в cpython? Должен ли этот список, хранящийся в a, занимать место, освобожденное первым dict? – Laurence Gonsalves 2 November 2010 в 22:52
  • 3
    @ Лоуренс: Нет, не обязательно. Распределители сложны и сильно оптимизированы; они не просто берут первый доступный адрес. В этом случае объект dict и объект списка имеют очень разные размеры, что, вероятно, помещает их в разные ведра распределения. – Glenn Maynard 2 November 2010 в 23:37
  • 4
    В Python 3.x способ работы распределителей (на высоком уровне) - документированная часть C API , а не захоронение в комментариях в источнике, хотя я думаю, что специальный пользовательский список и dict / set allocators и freelists регистрируются только в источнике ( Objects/listobject.c и dictobject.c). – abarnert 27 May 2015 в 04:11
  • 5
    Другой способ увидеть этот фрагмент: x = []; i = id(x); del x; gc.collect(); i == id([]). Если вы отпустите вызов gc.collect(), это (скорее всего) вернет False, в противном случае (вероятно) True. – filmor 9 December 2015 в 11:48

Оператор == на списках и dicts не сравнивает идентификаторы объектов, чтобы увидеть, являются ли они одним и тем же объектом. Для этого используйте obj1 is obj2.

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

-4
ответ дан Dave Kirby 21 August 2018 в 19:14
поделиться
  • 1
    Он не сравнивает [] == [], он сравнивает id([]) == id([]). – Glenn Maynard 6 October 2010 в 23:09
  • 2
    Обратите внимание, что он не сравнивает списки и dicts, а их id(). – Thomas Wouters 6 October 2010 в 23:09
  • 3
    ОП не пытается это сделать. – Marcelo Cantos 6 October 2010 в 23:10
  • 4
    Фактически, большинство реализаций == проверяется с помощью оператора is, прежде чем выполнять проверку члена. Причина, заключающаяся в том, что два объекта с одним и тем же идентификатором должны иметь одинаковый контент. Но вы правы, что сравнение id() должно выполняться с использованием оператора is вместо id(a) == id(b); и что принятие id () объекта обычно бессмысленно. – Lie Ryan 6 October 2010 в 23:16
  • 5
    @Lie Ryan интересно, что в этом случае не работает: [] is [] - False. Я предполагаю, что передача первого [] в id создает область для его выхода. – aaronasterling 6 October 2010 в 23:53

он не работает одинаково в Jython ...

>>> id({})
1
>>> id([])
2

Может ли быть оптимизация, когда обычно используемые (т.е. пустые) контейнеры «интернированы», чтобы сэкономить на расходах на размещение ?

Это (в CPython) не предполагает:

>>> def mutateid(obj):
...   obj.append('x')
...   print obj
...   print id(obj)
... 
>>> mutateid([])
['x']
4299590472
>>> id([])
4299590472
>>> 
-1
ответ дан phlip 21 August 2018 в 19:14
поделиться
  • 1
    Это по двум причинам: на самом деле Jython использует GC GC, что означает, что объекты не собираются, как только последняя ссылка исчезает (например, в CPython). Во-вторых, поскольку объекты Java не находятся в фиксированных ячейках памяти (например, в CPython), Jython не может использовать адрес памяти объекта для своего идентификатора. Он должен использовать что-то еще, сохраняя семантику id(). Насколько я помню, Jython использует счетчик, который начинает отсчет, когда вы вызываете id() на объект. – Thomas Wouters 6 October 2010 в 23:11
  • 2
    Этот код действительно не проверяет то же самое явление, о котором спрашивает OP. Что возвращает id({}) == id({}) в Jython? – Marcelo Cantos 6 October 2010 в 23:12
  • 3
    & GT; & GT; & GT; id ({}) == id ({}) False & gt; & gt; & gt; & gt; – phlip 6 October 2010 в 23:25

Когда вы вызываете id({}), Python создает dict и передает его функции id. Функция id принимает свой идентификатор (ячейку памяти) и отбрасывает dict. Дик разрушен. Когда вы делаете это дважды в быстрой последовательности (без каких-либо других dicts, создаваемых в среднее время), dict Python создает второй раз, когда используется тот же блок памяти, что и в первый раз. (Распределитель памяти CPython делает это намного более вероятным, чем кажется). Поскольку (в CPython) id использует память в качестве идентификатора объекта, идентификатор двух объектов одинаковый. Это, очевидно, не происходит, если вы назначаете dict переменной и затем получаете ее id(), потому что dicts живы одновременно , поэтому их id должны быть разными.

Мутируемость не вступает в игру, а кеширует кеширование кортежей и строк. В том же объекте кода (функция или тело тела тела или тела модуля) будут повторно использоваться те же литералы (целые числа, строки и некоторые кортежи). Mutable objects никогда не могут быть повторно использованы, они всегда создаются во время выполнения.

Короче говоря, идентификатор объекта уникален только для времени жизни объекта . После уничтожения объекта или до его создания что-то еще может иметь один и тот же идентификатор.

38
ответ дан Thomas Wouters 21 August 2018 в 19:14
поделиться
  • 1
    Есть ли более короткий способ сказать «голос-вверх-вверх-вперед-ansewr-and-ignore-the-rest-whatever-of-merit-itis»? – Glenn Maynard 6 October 2010 в 23:17
  • 2
    Сорт Гленн, вы отмечаете это как ответ :) – spenthil 6 October 2010 в 23:50
  • 3
    @spenthil: Отметьте-верх-ответ-правильно-игнорируйте-the-clearer-answer-below-it-itis? Это действительно так и происходит. :П – Glenn Maynard 6 October 2010 в 23:52
  • 4
    Не комментируя относительные достоинства ответов, я считаю, что upvotes следует масштабировать, например. стоит some_constant * log(upvoter_rep) / log(answerer_rep) – John Machin 7 October 2010 в 00:38
  • 5
    @Glenn: Я не уверен, почему мой ответ имеет меньше преимуществ, чем ваш. Конечно, это длиннее, и в нем нет экспериментов, которые вы делали в своей, но это потому, что я действительно знаю эти вещи из источника CPython. Не нужно экспериментировать. – Thomas Wouters 7 October 2010 в 00:46
Другие вопросы по тегам:

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