如何在Python中将字符串转换为int

ʞɔı*_*ɔıu 154 python arrays string

如何在python中将字符串转换为int?

这样说: 'y\xcc\xa6\xbb'

我想出了一个聪明/愚蠢的方法:

sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))
Run Code Online (Sandbox Code Playgroud)

我知道必须有内置或标准库中的内容,这样做更简单...

这与转换可以使用int(xxx,16)的十六进制数字字符串不同,而是我想转换一串实际字节值.

更新:

我有点像詹姆斯的答案好一点,因为它不需要导入另一个模块,但Greg的方法更快:

>>> from timeit import Timer
>>> Timer('struct.unpack("<L", "y\xcc\xa6\xbb")[0]', 'import struct').timeit()
0.36242198944091797
>>> Timer("int('y\xcc\xa6\xbb'.encode('hex'), 16)").timeit()
1.1432669162750244
Run Code Online (Sandbox Code Playgroud)

我的hacky方法:

>>> Timer("sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))").timeit()
2.8819329738616943
Run Code Online (Sandbox Code Playgroud)

进一步更新:

有人在评论中询问导入另一个模块的问题是什么.好吧,导入模块不一定便宜,看看:

>>> Timer("""import struct\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""").timeit()
0.98822188377380371
Run Code Online (Sandbox Code Playgroud)

包括导入模块的成本几乎抵消了该方法的所有优点.我相信这只会包括在整个基准测试中导入一次的费用; 看看我每次强迫它重装时会发生什么:

>>> Timer("""reload(struct)\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""", 'import struct').timeit()
68.474128007888794
Run Code Online (Sandbox Code Playgroud)

毋庸置疑,如果你在每次导入时执行大量的这种方法,那么这个问题就会成比例地减少.它也可能是i/o成本而不是cpu,因此它可能取决于特定机器的容量和负载特性.

Mec*_*ail 300

在Python 3.2及更高版本中,使用

>>> int.from_bytes(b'y\xcc\xa6\xbb', byteorder='big')
2043455163
Run Code Online (Sandbox Code Playgroud)

要么

>>> int.from_bytes(b'y\xcc\xa6\xbb', byteorder='little')
3148270713
Run Code Online (Sandbox Code Playgroud)

根据你的字节串的字节顺序.

这也适用于任意长度的bytestring-integers,以及通过指定的二进制补码有符号整数signed=True.请参阅文档from_bytes.

  • @eri我复活了一个用于评估几种CRC方法的timeit脚本.四次运行1)struct 2)int.from_bytes 3)as#1但cython编译,4)as#2但是cython编译.结构为330ns,int为1.14us(cython在两者中可能加速20ns ......)看起来我正在切换回来:)这不是过早的优化,我一直在遇到一些令人讨厌的瓶颈,特别是有一百万个样本要发布进程并一直在敲打零件. (5认同)

Gre*_*ill 106

您还可以使用struct模块执行此操作:

>>> struct.unpack("<L", "y\xcc\xa6\xbb")[0]
3148270713L
Run Code Online (Sandbox Code Playgroud)

  • 这个答案不适用于任意长度的二进制字符串. (57认同)
  • Rafał:不是真的,因为Greg使用<,根据文档L是标准大小(4)"当格式字符串以'<','>','!'之一开头时 或'='." http://docs.python.org/library/struct.html#format-characters (11认同)
  • 类型具有特定的大小,它永远不会适用于任意长度的二进制字符串.如果你知道每个项目的类型,你可以设置一个for循环来处理它. (4认同)
  • 警告:"L"实际上是64位Python构建中的8个字节(而不是4个),因此可能会失败. (3认同)
  • “L”实际上是 uint32(4 个字节)。如果在我的情况下您需要 8 个字节,请使用“Q”--&gt; uint64。还要注意 "l"--&gt;int32 和 q--&gt;int64 (2认同)

Jam*_*ill 66

正如Greg所说,如果你正在处理二进制值,你可以使用struct,但是如果你只有一个"十六进制数"但是以字节格式,你可能只想转换它:

s = 'y\xcc\xa6\xbb'
num = int(s.encode('hex'), 16)
Run Code Online (Sandbox Code Playgroud)

......这跟:

num = struct.unpack(">L", s)[0]
Run Code Online (Sandbox Code Playgroud)

...除了它可以用于任何数量的字节.

  • "二进制值"与"十六进制数"之间的区别究竟是什么,但是以字节格式"??????? (3认同)
  • 顺便说一句,这个答案假设整数是以big-endian字节顺序编码的.对于little-endian命令,执行:`int(''.join(reversed(s)).encode('hex'),16)` (3认同)

小智 8

我使用以下函数在int,hex和bytes之间转换数据.

def bytes2int(str):
 return int(str.encode('hex'), 16)

def bytes2hex(str):
 return '0x'+str.encode('hex')

def int2bytes(i):
 h = int2hex(i)
 return hex2bytes(h)

def int2hex(i):
 return hex(i)

def hex2int(h):
 if len(h) > 1 and h[0:2] == '0x':
  h = h[2:]

 if len(h) % 2:
  h = "0" + h

 return int(h, 16)

def hex2bytes(h):
 if len(h) > 1 and h[0:2] == '0x':
  h = h[2:]

 if len(h) % 2:
  h = "0" + h

 return h.decode('hex')
Run Code Online (Sandbox Code Playgroud)

资料来源:http://opentechnotes.blogspot.com.au/2014/04/convert-values-to-from-integer-hex.html


Raf*_*ird 6

import array
integerValue = array.array("I", 'y\xcc\xa6\xbb')[0]
Run Code Online (Sandbox Code Playgroud)

警告:以上内容特别针对特定于平台."I"说明符和string-> int转换的字节顺序都取决于您的特定Python实现.但是如果你想一次转换很多整数/字符串,那么数组模块就可以快速完成.


Tet*_*lux 5

在Python 2.x中,您可以使用<B无符号字节的格式说明符,以及<bstruct.unpack/的带符号字节struct.pack.

例如:

x='\xff\x10\x11'

data_ints = struct.unpack('<' + 'B'*len(x), x) # [255, 16, 17]
Run Code Online (Sandbox Code Playgroud)

和:

data_bytes = struct.pack('<' + 'B'*len(data_ints), *data_ints) # '\xff\x10\x11'
Run Code Online (Sandbox Code Playgroud)

*是必需的!

看到 https://docs.python.org/2/library/struct.html#format-characters获取格式说明符列表.