1

我想将整数序列与单个字节字符串中的标记列表连接起来,例如,以下内容:

foo
bar
baz

将变为(整数表示为 1 个字节):

b'\x00foo'
b'\x01bar'
b'\x02baz'

我想出的最好的看起来像这样:

for i, token in zip(range(256), "foo bar baz".split()):
    print(i.to_bytes(1, sys.byteorder) + token.encode())

然而,迭代本身涉及循环中每个步骤的 Python 整数和字节之间的转换,因此它比简单地迭代整数要慢得多(对我来说是 10 倍)。

问题是:有没有办法直接迭代整数的字节字符串表示,而不是整数本身?

4

3 回答 3

2

您可以使用 numpy 并直接访问缓冲区接口以避免转换:

在 python 2.7(numpy 1.7.1)上,这段代码:

N = arange(256, dtype='uint8')
for i, token in enumerate("foo bar baz".split()):
    print repr(N.data[i] + token.encode())

给出:

'\x00foo'
'\x01bar'
'\x02baz'
于 2013-07-05T17:29:54.240 回答
1

如果是固定宽度的标记(比如说 3 个字符),可以使用一个 numpy 记录数组。

如果您的目的不仅是打印数据,而且以某种方便的形式以特定的位顺序存储数据,这将非常方便。当然,元素/记录的数量越长,这种方法的效率就越高。

在以下示例中,字符串长度固定为 3:

# Create a record array
x = np.zeros((3,),dtype=('u1,a3'))
# Fill the array
x[:] = [(n,s) for n, s in zip(arange(256, dtype='u1'), 'foo bar bax'.split())]

输出:

array([(0, 'foo'), (1, 'bar'), (2, 'bax')], 
      dtype=[('f0', 'u1'), ('f1', 'S3')])

现在您可以使用所有 numpy 函数来处理数据。例如,您可以通过以下方式获取数字字段(字段 0,默认命名为“f0”)的数组:

x['f0']

和字符串字段:

x['f1']

这些是原始数组的“视图”,不会使用更多内存。有关 numpy 记录数组的更多信息,请参阅numpy 文档

注意:据我所知,这种方法应该适用于 python 2.x 和 3.x。

于 2013-07-05T18:52:36.863 回答
1

我认为可能会更快:

from struct import pack

for i, token in enumerate(b"foo bar bazq".split()):
    print(pack('@B%ds' % len(token), i, token))

输出:

b'\x00foo'
b'\x01bar'
b'\x02bazq'

如果您只有或想要 3 个字符串,您可以使用更简单的print函数/语句:

    print(pack('@B3s', i, token))
于 2013-07-05T17:45:50.257 回答