Python 将具有相同哈希的两个键放入dict

Python 将具有相同哈希的两个键放入dict,python,dictionary,python-2.x,Python,Dictionary,Python 2.x,上面,我创建了一个dict,其中有一个哈希冲突,两个插槽被占用 >>> one_decimal = Decimal('1') >>> one_complex = complex(1,0) >>> d = {one_decimal: '1D', one_complex: '1C'} >>> len(d) 2 >>> map(hash, d) [1, 1] 如何处理整数1的getitem?索引是如何为复杂的文

上面,我创建了一个dict,其中有一个哈希冲突,两个插槽被占用

>>> one_decimal = Decimal('1')
>>> one_complex = complex(1,0)
>>> d = {one_decimal: '1D', one_complex: '1C'}
>>> len(d)
2
>>> map(hash, d)
[1, 1]
如何处理整数
1
的getitem?索引是如何为复杂的文字索引解析正确的值的

Python 2.7.12/Linux。

正如@CoryKramer所述,哈希相等并不意味着对象相等。Python字典可以包含任意数量的散列相等的元素,只要对象本身不相等

对您的问题的简短回答可能是,从2.7开始,Python库中的
complex
类型的实现有点不完整。正如@wim所指出的,使用
=
比较
int
complex
效果很好,但比较
十进制
复数
则不行。由于比较
one_decimal==one_complex
由于其类型的不同,将始终返回
False
,因此它们都可以在Python 2.7中的同一个字典中存在

这个问题在Python3中已经修复。我在3.5中进行实验,
1个十进制数
1个复数
是相等的。运行相同的代码段后,字典会按照预期(第一个键,最后一个值)在键
one\u decimal
下包含
one\u complex
的值

TL;博士
这是Py2.7的
complex
类型中的一个bug。Py3中已修复。

问题仅在使用带复数的十进制时出现。Float、int等可以很好地工作,因为它们被强制用于比较

在decimal lib中,与复数进行比较的操作具体如下:

在python2中,函数实现为:

    # Comparisons with float and complex types.  == and != comparisons
    # with complex numbers should succeed, returning either True or False
    # as appropriate.  Other comparisons return NotImplemented.
    if equality_op and isinstance(other, _numbers.Complex) and other.imag == 0:
        other = other.real
为什么
len(set([1,Decimal('1'),(1+0j)])==2
是因为首先将小数与int进行比较,如果更改顺序,则会得到不同的输出:

def _convert_other(other, raiseit=False, allow_float=False):
    """Convert other to Decimal.

    Verifies that it's ok to use in an implicit construction.
    If allow_float is true, allow conversion from float;  this
    is used in the comparison methods (__eq__ and friends).

    """
    if isinstance(other, Decimal):
        return other
    if isinstance(other, (int, long)):
        return Decimal(other)
    if allow_float and isinstance(other, float):
        return Decimal.from_float(other)

    if raiseit:
        raise TypeError("Unable to convert %s to Decimal" % other)
    return NotImplemented

另外,如果插入的顺序与文档相匹配,那么使用文本会更好,因为在最后一个值中,在集合(..)上使用文本。

Python可以。比散列冲突更让我困扰的是
one_decimal==one_complex
True
。有趣的是,正是因为这个原因,这在Py3中不起作用。更有趣的是:
len(set([decimal('1'),(1+0j)]
是2,但是
len set([1,decimal('1'),(1+0j)])
是1。我想你应该看看:
def _convert_other(other, raiseit=False, allow_float=False):
    """Convert other to Decimal.

    Verifies that it's ok to use in an implicit construction.
    If allow_float is true, allow conversion from float;  this
    is used in the comparison methods (__eq__ and friends).

    """
    if isinstance(other, Decimal):
        return other
    if isinstance(other, (int, long)):
        return Decimal(other)
    if allow_float and isinstance(other, float):
        return Decimal.from_float(other)

    if raiseit:
        raise TypeError("Unable to convert %s to Decimal" % other)
    return NotImplemented
In [23]: {1, Decimal('1'), (1+0j)}
Out[23]: {(1+0j), Decimal('1')}

In [24]: {Decimal('1'),1, (1+0j)}
Out[24]: {(1+0j), Decimal('1')}

In [25]: {Decimal('1'), (1+0j), 1}
Out[25]: {1}