gpt4 book ai didi

Python 位列表到字节列表

转载 作者:太空宇宙 更新时间:2023-11-03 14:17:11 24 4
gpt4 key购买 nike

我有一个很长的一维整数 1 和 0 列表,代表 8 位二进制字节。从中创建包含整数字节的新列表的简洁方法是什么。

我熟悉 C,但对 Python 不熟悉,所以我按照使用 C 的方式对其进行了编码:一个遍历每一位的复杂结构。然而,我知道 Python 相对于 C 的全部意义在于这些事情通常可以紧凑而优雅地完成,我应该学习如何做到这一点。也许使用列表理解?

这行得通,但对于更“Pythonic”方式的建议将不胜感激:

#!/usr/bin/env python2
bits = [1,0,0,1,0,1,0,1,0,1,1,0,1,0,1,1,1,1,1,0,0,1,1,1]
bytes = []
byt = ""
for bit in bits:
byt += str(bit)
if len(byt) == 8:
bytes += [int(byt, 2)]
byt = ""
print bytes

$ bits-to-bytes.py
[149, 107, 231]

最佳答案

您可以将列表分成 8 个元素的 block 并将子元素映射到 str:

[int("".join(map(str, bits[i:i+8])), 2) for i in range(0, len(bits), 8)]

你可以把它分成两部分映射和连接一次:

mapped = "".join(map(str, bits))
[int(mapped[i:i+8], 2) for i in range(0, len(mapped), 8)]

或者用iter 借用grouper recipe在 itertools 中:

it = iter(map(str, bits))
[int("".join(sli), 2) for sli in zip(*iter([it] * 8))]

iter(map(str, bits)) 将 bits 的内容映射到 str 并创建一个 iterator , zip(*iter([it] * 8)) 将元素分组为 8 个子元素组。
每个 zip(*iter.. 从我们的迭代器中消耗八个子元素,所以我们总是得到顺序组,它与第一个代码中的切片逻辑相同,我们只是避免了切片的需要。

正如 Sven 评论的那样,对于不能被 n 整除的列表,您将使用与原始代码类似的 zip 丢失数据,您可以调整我链接的石斑鱼食谱来处理这些情况:

from itertools import zip_longest # izip_longest python2

bits = [1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1,1,0]
it = iter(map(str, bits))

print( [int("".join(sli), 2) for sli in izip_longest(*iter([it] * 8),fillvalue="")])
[149, 107, 231, 2] # using just zip would be [149, 107, 231]

fillvalue="" 意味着我们用空字符串填充奇数长度组,这样我们仍然可以调用 int("".join(sli), 2) 和在采用 3 * 8 block 后得到 1,0 的正确输出。

在你自己的代码中 bytes += [int(byt, 2)] 可以简单地变成 bytes.append(int(byt, 2))

关于Python 位列表到字节列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32284940/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com