int.to_bytes
int 对象有一个 to_bytes 方法,可用于将 int 转换为其对应的字节:
>>> import sys
>>> [i.to_bytes(1, sys.byteorder) for i in b'123']
[b'1', b'2', b'3']
与其他一些答案一样,目前尚不清楚这是否比 OP 的原始解决方案更具可读性:我认为长度和字节顺序参数使其更加嘈杂。
struct.unpack
另一种方法是使用struct.unpack,尽管这也可能被认为难以阅读,除非您熟悉 struct 模块:
>>> import struct
>>> struct.unpack('3c', b'123')
(b'1', b'2', b'3')
(正如 jfs 在 cmets 中观察到的,struct.unpack 的格式字符串可以动态构造;在这种情况下,我们知道结果中的单个字节数必须等于原始字节串中的字节数,所以 @987654327 @ 是可能的。)
性能
>>> import random, timeit
>>> bs = bytes(random.randint(0, 255) for i in range(100))
>>> # OP's solution
>>> timeit.timeit(setup="from __main__ import bs",
stmt="[bytes([b]) for b in bs]")
46.49886950897053
>>> # Accepted answer from jfs
>>> timeit.timeit(setup="from __main__ import bs",
stmt="[bs[i:i+1] for i in range(len(bs))]")
20.91463226894848
>>> # Leon's answer
>>> timeit.timeit(setup="from __main__ import bs",
stmt="list(map(bytes, zip(bs)))")
27.476876026019454
>>> # guettli's answer
>>> timeit.timeit(setup="from __main__ import iter_bytes, bs",
stmt="list(iter_bytes(bs))")
24.107485140906647
>>> # user38's answer (with Leon's suggested fix)
>>> timeit.timeit(setup="from __main__ import bs",
stmt="[chr(i).encode('latin-1') for i in bs]")
45.937552741961554
>>> # Using int.to_bytes
>>> timeit.timeit(setup="from __main__ import bs;from sys import byteorder",
stmt="[x.to_bytes(1, byteorder) for x in bs]")
32.197659170022234
>>> # Using struct.unpack, converting the resulting tuple to list
>>> # to be fair to other methods
>>> timeit.timeit(setup="from __main__ import bs;from struct import unpack",
stmt="list(unpack('100c', bs))")
1.902243083808571
struct.unpack 似乎比其他方法至少快一个数量级,大概是因为它在字节级别上运行。另一方面,int.to_bytes 的性能比大多数“显而易见”的方法都要差。