Python 合并2字节数组的最佳方法是什么?

Python 合并2字节数组的最佳方法是什么?,python,Python,让我们假设我有两个bigs数组(我在本例中放置了较小的数组): 我要做的是以这种方式合并这两个阵列: [10,20 , 11,21 , 30,40 , 31,41 , ... 我想从第一个数组中取出2个字节,然后从第二个数组中取出2个字节,以此类推 这就是我所做的。它可以工作,但我认为有一种最好的方法可以做到这一点,而不必创建中间产品阵列: a3 = bytearray() for i in range(0, len(a1), 2): a3.append(a1[i]) a3.a

让我们假设我有两个bigs数组(我在本例中放置了较小的数组):

我要做的是以这种方式合并这两个阵列:

[10,20 , 11,21 , 30,40 , 31,41 , ...
我想从第一个数组中取出2个字节,然后从第二个数组中取出2个字节,以此类推

这就是我所做的。它可以工作,但我认为有一种最好的方法可以做到这一点,而不必创建中间产品阵列:

a3 = bytearray()
for i in range(0, len(a1), 2):
    a3.append(a1[i])
    a3.append(a1[i+1])
    a3.append(b1[i])
    a3.append(b1[i+1])

output_array=bytes(a3)  # Very important: i need bytes() object at the end

您可以使用切片分配来执行此操作:

a1 = bytes([10,20,30,40,50,60,70,80])
a2 = bytes([11,21,31,41,51,61,71,81])

n = len(a1)

a3 = bytearray(2*n)
a3[0::4] = a1[0::2]
a3[1::4] = a1[1::2]
a3[2::4] = a2[0::2]
a3[3::4] = a2[1::2]
a3 = bytes(a3)
输出:

>>> a3
b'\n\x14\x0b\x15\x1e(\x1f)2<3=FPGQ'
>>> list(a3)
[10, 20, 11, 21, 30, 40, 31, 41, 50, 60, 51, 61, 70, 80, 71, 81]
从此处获取的块:
合并从这里开始:

结合以下内容:

def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]

a1 = [10,20,30,40,50,60,70,80]
b1 = [11,21,31,41,51,61,71,81]
combined = [j for i in zip(chunks(a1, 2),chunks(b1, 2)) for j in i]
out = bytes(bytearray([x for pair in combined for x in pair]))
==> b'\n\x14\x0b\x15\x1e(\x1f)2<3=FPGQ'
def块(l,n):
“”“从l生成连续的n大小的块。”
对于范围(0,len(l),n)内的i:
收益率l[i:i+n]
a1=[10,20,30,40,50,60,70,80]
b1=[11,21,31,41,51,61,71,81]
组合=[j代表zip中的i(块(a1,2),块(b1,2))代表i中的j]
out=字节(bytearray([x表示成对输入,x表示成对输入])

==>b'\n\x14\x0b\x15\x1e(\x1f)2这是另一个选项:

a1=bytes([10,20,30,40,50,60,70,80])
a2=bytes([11,21,31,41,51,61,71,81])

merged = bytes((a1 if (i&3)<2 else a2)[i-(i&2)-2*(i>>2)]
               for i in range(2*len(a1)))
a1=字节([10,20,30,40,50,60,70,80])
a2=字节([11,21,31,41,51,61,71,81])
合并=字节((如果(i&3)>2,则为a1)]
对于范围(2*len(a1))内的i

直接在字节上使用片分配

a1 = bytes([10,20,30,40,50,60,70,80])
a2 = bytes([11,21,31,41,51,61,71,81])
a3 = bytes()

for i in range(int(len(a1)/2)):
    a3 += a1[i*2:i*2+2] + a2[i*2:i*2+2]
# a3 = b'\n\x14\x0b\x15\x1e(\x1f)2<3=FPGQ'
a1=字节([10,20,30,40,50,60,70,80])
a2=字节([11,21,31,41,51,61,71,81])
a3=字节()
对于范围内的i(int(len(a1)/2)):
a3+=a1[i*2:i*2+2]+a2[i*2:i*2+2]

#a3=b'\n\x14\x0b\x15\x1e(\x1f)2你认为我可以做更少的拷贝吗?最后一行是复印件吗?是的,最后一行是复印件。我会试着想出一种方法,不用最后一个拷贝……结果你的第一个解决方案(带切片)比第二个快得多。是的,我一点也不惊讶。它使用了经过高度优化的CPython部件。但速度并不是尝试避免复制的唯一可能原因(也可能存在内存限制)。请注意,您选择的答案会在每个片上复制一个副本。对于10000个数字的列表,wim的答案比Dekel的快100倍(50.3µs vs 4.28 ms),我认为每个a3+=运算将创建并复制到一个新字节()对象
a1=bytes([10,20,30,40,50,60,70,80])
a2=bytes([11,21,31,41,51,61,71,81])

merged = bytes((a1 if (i&3)<2 else a2)[i-(i&2)-2*(i>>2)]
               for i in range(2*len(a1)))
a1 = bytes([10,20,30,40,50,60,70,80])
a2 = bytes([11,21,31,41,51,61,71,81])
a3 = bytes()

for i in range(int(len(a1)/2)):
    a3 += a1[i*2:i*2+2] + a2[i*2:i*2+2]
# a3 = b'\n\x14\x0b\x15\x1e(\x1f)2<3=FPGQ'