【问题标题】:Python: how can this code use negative integer 0 as a distinct index value?Python:这段代码如何使用负整数 0 作为不同的索引值?
【发布时间】:2025-12-08 14:50:02
【问题描述】:

我的算法采用列表[0,-0,1,-1,2,-2,3,-3] 等,并在伪代码中执行以下操作:

while list:
    d = list.pop()
    objects[abs(d)] *= sign(d)

您可以在这里看到为什么需要-0。如果我单独存储符号或从 1 或其他东西索引,我的代码必须不那么优雅。如何让 python 存储 0-0

编辑: 基本上我正在实施回溯搜索。因此,该列表中的变量以任意顺序排列,减号表示设置为 false。它通过并将 0 设置为 true,然后将 0 设置为 false,然后将 1 设置为 true,然后将 -1 设置为 false,等等。在我看来,最优雅的方法是将真值与索引结合使用减号。

编辑: 我找到了一种更好的方法来使用双端队列来做我想做的事情。我会留下这个问题,以免浪费这里的答案。

【问题讨论】:

  • 在 C 语言中,在二进制补码机器(几乎所有现代平台)上,为整数 0 设置符号位不会给你 -0,它会给你2147483648
  • 您可以使用-0.0。如果您的列表是固定的,为什么不从0 数到n 并同时执行正面和负面案例?
  • 更一般地说,C 和 Python 一样,没有 -0 作为整数,但可能有 -0 作为 float(在 IEEE 浮动平台上,这又是几乎所有现代平台)。
  • 看起来您正在索引一个单独的数组并从它的两侧开始。你能描述一下你真正想要做什么吗?
  • 至于为什么没有-0,它几乎没有那么有用。当浮点计算从负数下溢时,-0.0 表示有用的信息。整数没有任何类似的下溢条件,并且为 -0 保留位模式会产生尴尬的结果。

标签: python indexing


【解决方案1】:

按照 Blender 的建议,使用浮点数和函数 copysign

import math
list=[0.0,-0.0,1.0,-1.0,2.0,-2.0,3.0,-3.0]
objects={}
while list:
    d = round(list.pop(),10)
    if d not in objects:
        objects[d]=1.0
    objects[d] *= math.copysign(1.0,d)

【讨论】:

  • 您实际上不能用浮点数索引列表,即使浮点数具有整数值。
  • @user2357112 :所以强制它:objects[int(d)] ...
  • 浮点数可以用作字典的键,但我们必须使用 round() 规范化键空间
  • round(d, 10) 没有帮助。首先,round 仍然返回一个浮点数,而不是一个整数。其次,为什么四舍五入到只有 10 位十进制数字会使事情变得更加 int-ish?
  • @Navith:是的,但是list[-1] 可能无论如何都不会做 OP 所期望的,它的行为取决于列表的长度。这个例子是人为的。你们中的任何人都知道OP真正想要做什么吗?我不。也许他们只需要enumerate(list_of_signs)
【解决方案2】:

这是另一个不涉及使用浮动的可能解决方案。 我们可以使用emulating numeric types 的魔术方法定义一个类,当我们尝试获取其符号时,它的功能为-1,当我们将其用作数组的索引时,它的功能为0

class NegativeZero:
    def __index__(self):
       return 0
    def __int__(self):
       return -1
    def __abs__(self):
       return 0

N = NegativeZero()

myList = [0,N,1,-1,2,-2,3,-3]
while myList:
    d = myList.pop()
    objects[abs(d)] *= sign(int(d))

【讨论】:

  • 列表可以有任意顺序,例如[-1,-0,1,0,2,-2]
  • @RenéG,我知道你找到了另一种方法,但如果你好奇,有一种方法可以通过类来做到这一点。
  • __index____int__ 返回不同的值是一种误导。如果您尝试在任何其他上下文中使用此值(例如将其乘以另一个数字),它的行为将不会像 -0
  • @abarnert 这是非常正确的,但操作有一个非常具体的问题。
  • 当然,假设此列表中的值不会用于其他任何用途。