LINUX.ORG.RU

История изменений

Исправление tz4678, (текущая версия) :

Там, кстати, эффект даже интересней:

In [1]: q={}

In [2]: q[1.0]='foo'

In [3]: q
Out[3]: {1.0: 'foo'}

In [4]: q[1]='foo'

In [5]: q
Out[5]: {1.0: 'foo'}

In [6]: q[2]='foo'

In [7]: q
Out[7]: {1.0: 'foo', 2: 'foo'}

In [8]: import dis

In [9]: def f():
   ...:     q = {}
   ...:     q[1.0] = 'foo'
   ...:     q[1] = 'bar'
   ...: 

In [10]: dis.dis(f)
  2           0 BUILD_MAP                0
              2 STORE_FAST               0 (q)

  3           4 LOAD_CONST               1 ('foo')
              6 LOAD_FAST                0 (q)
              8 LOAD_CONST               2 (1.0)
             10 STORE_SUBSCR

  4          12 LOAD_CONST               3 ('bar')
             14 LOAD_FAST                0 (q)
             16 LOAD_CONST               4 (1)
             18 STORE_SUBSCR
             20 LOAD_CONST               0 (None)
             22 RETURN_VALUE

STORE_SUBSCR

Эта функция интересно работает

int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)

Пример магии:

In [11]: q = {1: 'Foo'}

In [12]: q[True] = 'Bar'

In [13]: q
Out[13]: {1: 'Bar'}

1, 1.0 и True с точки зрения питона один и тот же ключ

А разгадка в функции хеширования:

In [14]: hash(1)
Out[14]: 1

In [15]: hash(1.0)
Out[15]: 1

In [16]: hash(True)
Out[16]: 1

Словарь - это просто хеш-таблица.

Исходная версия tz4678, :

Там, кстати, эффект даже интересней:

In [1]: q={}

In [2]: q[1.0]='foo'

In [3]: q
Out[3]: {1.0: 'foo'}

In [4]: q[1]='foo'

In [5]: q
Out[5]: {1.0: 'foo'}

In [6]: q[2]='foo'

In [7]: q
Out[7]: {1.0: 'foo', 2: 'foo'}

In [8]: import dis

In [9]: def f():
   ...:     q = {}
   ...:     q[1.0] = 'foo'
   ...:     q[1] = 'bar'
   ...: 

In [10]: dis.dis(f)
  2           0 BUILD_MAP                0
              2 STORE_FAST               0 (q)

  3           4 LOAD_CONST               1 ('foo')
              6 LOAD_FAST                0 (q)
              8 LOAD_CONST               2 (1.0)
             10 STORE_SUBSCR

  4          12 LOAD_CONST               3 ('bar')
             14 LOAD_FAST                0 (q)
             16 LOAD_CONST               4 (1)
             18 STORE_SUBSCR
             20 LOAD_CONST               0 (None)
             22 RETURN_VALUE

STORE_SUBSCR

Эта функция интересно работает

int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)

Пример магии:

In [11]: q = {1: 'Foo'}

In [12]: q[True] = 'Bar'

In [13]: q
Out[13]: {1: 'Bar'}

1, 1.0 и True с точки зрения питона один и тот же ключ

А разгадка в функции хеширования:

In [14]: hash(1)
Out[14]: 1

In [15]: hash(1.0)
Out[15]: 1

In [16]: hash(True)
Out[16]: 1