出现以下问题,因为我试图使用bytes
字符串作为字典键,而我理解为相等的字节值未被视为相等。
为什么下面的python代码不相等-相同二进制数据的这两个等效表示(不是故意选择以避免偏执的示例?)
b'0b11111111' == b'0xff'
我知道以下内容正确,证明了对等:
int(b'0b11111111', 2) == int(b'0xff', 16)
但是python为什么要强迫我知道表示形式?它与字节序有关吗?除了将它们全部转换为例如,是否有一些简单的方法来迫使它们比较等效项十六进制字面量?任何人都可以提出一种透明且清晰的方法,以一种(某种)平台独立的方式在所有表示之间切换(或者我问得太多)吗?
编辑:
给出下面的评论,说我想使用b'0b11111111'
形式的8位实际索引一个字典,那么python为什么将它扩展到10个字节,我该如何防止呢?
这是大型树数据结构的一小部分,将索引扩展80倍似乎是对内存的巨大浪费。
字节可以代表任何数量的事物。 Python无法而且不会猜测您的字节可能编码什么。
例如,int(b'0b11111111', 34)
是有效的解释,但该解释不等于十六进制FF。事实上,解释的数量是无止境的。字节可以表示一系列ASCII码点,图像颜色或音符。
除非您明确地应用解释,否则字节对象由范围为0-255的值序列的
just
组成,并且这些字节的文本表示形式如果可表示为可打印文本,则使用ASCII:>>> list(bytes(b'0b11111111'))
[48, 98, 49, 49, 49, 49, 49, 49, 49, 49]
>>> list(bytes(b'0xff'))
[48, 120, 102, 102]
那些字节序列不相等。
如果要将这些序列显式解释为整数文字,则使用ast.literal_eval()
解释
decoded
文本值;在比较之前总是先归一化:ast.literal_eval()
>>> import ast
>>> ast.literal_eval(b'0b11111111'.decode('utf8'))
255
>>> ast.literal_eval(b'0xff'.decode('utf8'))
255
包含10个字节: