将具有相同散列的两个键放入dict中

时间:2016-10-24 18:54:33

标签: python dictionary python-2.x

>>> one_decimal = Decimal('1')
>>> one_complex = complex(1,0)
>>> d = {one_decimal: '1D', one_complex: '1C'}
>>> len(d)
2
>>> map(hash, d)
[1, 1]

上面,我创建了一个带有哈希冲突的dict,并且占用了两个插槽。

>>> d[1]
'1D'
>>> d[1+0j]
'1C'

整数1如何处理getitem?索引如何设法解决复杂文字索引的正确值?

Python 2.7.12 / Linux。

2 个答案:

答案 0 :(得分:6)

正如@CoryKramer所提到的accepted answer所述,哈希的相等并不意味着对象的平等。只要对象本身不相等,Python字典就可以包含任意数量的具有相等哈希值的元素。

对于你的问题的简短回答可能是从{@ 1}}类型的实现在2.7中的Python库中有点不完整。正如@wim指出的那样,使用complex比较intcomplex可以正常工作,但比较==Decimal则不然。由于比较complex将始终返回one_decimal == one_complex,因为它们的类型,它们都可以存在于Python 2.7中的相同字典中。

此问题已在Python 3中修复。我正在3.5中进行试验,其中Falseone_decimal相等。运行相同的代码段后,字典会按照预期(第一个键,最后一个值)包含键one_complex下的one_complex值。

TL; DR

这是Py2.7的one_decimal类型中的错误。在Py3中修复。

答案 1 :(得分:3)

问题仅在于将十进制复杂号一起使用时。 Float's,int&s等工作正常,因为他们被强迫进行比较。

python3's十进制lib中,与复数相比,具体在_convert_for_comparison处理:

    # 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

在python2中,convert函数实现是:

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

为什么len(set([1, Decimal('1'), (1+0j)])) == 2是因为首先将 Decimal 与int进行比较,如果更改顺序,则会得到不同的输出:

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}

同样使用文字更好,因为您插入的顺序与文档匹配,因为最后一个值是preserved使用文字(...)。