История изменений
Исправление
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
Эта функция интересно работает
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
Эта функция интересно работает
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