Python字节文字的比较

Mat*_*mke 8 python comparison byte base endianness

出现了以下问题,因为我试图将bytes字符串用作字典键,而我理解为相等的字节值并未被视为相等.

为什么下面的python代码没有比较相同 - 不是这两个相同二进制数据的等价表示(为避免endianess而故意选择的例子)?

b'0b11111111' == b'0xff'
Run Code Online (Sandbox Code Playgroud)

我知道以下评估为真,证明了等价:

int(b'0b11111111', 2) == int(b'0xff', 16)
Run Code Online (Sandbox Code Playgroud)

但是为什么python强迫我知道代表?它与endian-ness有关吗?除了将它们全部转换为例如十六进制文字之外,还有一些简单的方法可以强制它们进行比较吗?任何人都可以建议一种透明而清晰的方法,以某种(某种程度上)平台无关的方式在所有表示之间移动(或者我要求的太多)?

编辑:

鉴于下面的评论,假设我想在表单中使用8位实际索引字典b'0b11111111',那么为什么python将其扩展为10个字节,我该如何防止这种情况?

这是一个较小的大型树数据结构,将我的索引扩展80倍似乎是对内存的巨大浪费.

Mar*_*ers 9

字节可以代表任何数量的东西.Python不能也不会猜测你的字节可能编码的内容.

例如,int(b'0b11111111', 34)同样一个有效的解释,但这种解释并不等于十六进制FF.

事实上,解释的数量是无穷无尽的.字节可以表示一系列ASCII码点,图像颜色或音符.

在明确应用解释之前,bytes对象包含0-255范围内的值序列,如果可以表示为可打印文本,则这些字节的文本表示使用ASCII:

>>> list(bytes(b'0b11111111'))
[48, 98, 49, 49, 49, 49, 49, 49, 49, 49]
>>> list(bytes(b'0xff'))
[48, 120, 102, 102]
Run Code Online (Sandbox Code Playgroud)

那些字节序列不相等.

如果要将这些序列显式解释为整数文字,则用于ast.literal_eval()解释已解码的文本值; 在比较之前总是先规范化:

>>> import ast
>>> ast.literal_eval(b'0b11111111'.decode('utf8'))
255
>>> ast.literal_eval(b'0xff'.decode('utf8'))
255
Run Code Online (Sandbox Code Playgroud)


unu*_*tbu 5

b'0b11111111' 由10个字节组成:

In [44]: list(b'0b11111111')
Out[44]: ['0', 'b', '1', '1', '1', '1', '1', '1', '1', '1']
Run Code Online (Sandbox Code Playgroud)

b'0xff'由4个字节组成:

In [45]: list(b'0xff')
Out[45]: ['0', 'x', 'f', 'f']
Run Code Online (Sandbox Code Playgroud)

显然,它们不是同一个对象.

Python重视显性.(显式优于隐式).它不假定b'0b11111111'是一定的整数的二进制表示.它只是一串字节.您必须明确说明如何解释它.