【问题标题】:Python: How to convert array of 4 digits to a larger number, bitwise?Python:如何按位将 4 位数组转换为更大的数字?
【发布时间】:2015-07-04 02:03:08
【问题描述】:

假设我有

array = [1,2,3,4]

我想要转换为数字1234;但是要取 1、2、3 和 4 的位,将它们连接起来并转换回一个数字。

换句话说,我可能必须将每个数字/数字转换为二进制,将它们连接起来,然后再转换回数字。

因此,1、2、3、4 将分别为 00000001000000100000001100000100。连接它们将导致 00000001000000100000001100000100 转换为无符号整数将是 16909060

请记住,数组中的数字来自ord(characters),因此它们的长度应该是 8 位,因此连接起来应该是一个 32 位的数字

我该怎么做?

【问题讨论】:

  • " ... 将每个数字/数字转换为二进制,将它们连接起来,然后转换回一个数字" for array 是您想要的结果[1, 10, 11, 100] => 11011100=> 220
  • edit您的问题显示您的预期结果。
  • @GordThompson 我刚刚为给定示例添加了所需的结果
  • 如果数组包含大于 255 的数字怎么办? (二进制表示将包含 9+ 位)

标签: python binary python-2.x


【解决方案1】:

在 Python 中操作字节数组的常用方法是使用 struct 模块。如有必要,请注意byte order

Python 3

>>> import struct
>>> i, = struct.unpack("<i", bytes([1, 2, 3, 4]))
>>> i
67305985
>>> 

Python 2 和 3

>>> import struct
>>> i, = struct.unpack("<i", struct.pack("4B", *[1, 2, 3, 4]))
>>> i
67305985
>>> 

【讨论】:

  • 嗯,构造完全返回struct.error: unpack requires a string argument of length 4。您的解决方案可能是 Python 3 独有的吗?我正在使用 Python 2.7
  • 是的,Python 3 中的 bytes 指的是 Python 2 中的 str 类型(因为 Python 3 str 是 Python 2 中的 unicode)。对于 Python 2,请使用 struct.pack("4B", *array) 而不是 bytes(array)
  • 不符合作为答案的条件。这段代码可能是一个很好的解决方案,但它足够晦涩,需要解释。
  • 这使用主机的字节顺序,这可能不是 OP 所期望的。
  • 虽然这足以让 OP 走上正轨,但无论如何。我改进了答案。谢谢你的cmets :)
【解决方案2】:
sum([v << i * 8 for i, v in enumerate(reversed(array))])

【讨论】:

  • 它实际上是 - 这里没有什么需要任何解释 - 枚举/反转可以在 python stdlib 文档中查找,列表理解在任何 python 教程/书中都有解释,我相信任何 python开发者理解它。
  • 谷歌几乎可以在这里回答每个问题,该网站的主要功能是使解决问题的谷歌搜索阶段变得更容易。
  • 复杂代码需要解释。这个尽可能简单。
  • @Veedrac 很抱歉 - 我在“低质量帖子”队列中找到了这个答案,正如你所看到的 - 相当大。大多数人甚至不评论类似的帖子,只投票关闭/删除它。我评论说,试图建议冰镇。看起来至少有 3 人同意它。也许不够礼貌,对此我很抱歉,(也很抱歉,冰镇)我的目标是提供建议而不是伤害他。下次我会评论你更礼貌的版本。
  • 我真的不在乎措辞,无需抱歉。虽然我仍然不同意你和其他 3 人的观点,但我明白你在没有试图理解问题/答案的情况下发表评论。
【解决方案3】:

在这种简单的情况下,这可能就足够了:

result = array[0] << 24 | array[1] << 16 | array[2] << 8 | array[3]

例如:

array = [1, 2, 3, 4]
result = array[0] << 24 | array[1] << 16 | array[2] << 8 | array[3]
print result

打印这个:

16909060

【讨论】:

  • 不知道为什么这被否决了。这似乎完全正确。所有其他答案都使用复杂的结构,而这个答案显示了它是多么简单。
  • 这非常简单。请问有没有办法反过来呢?那么给定 32 位整数,将其拆分为 4 个 8 位整数?我在想也许result &gt;&gt; 24 会给出第一个数字?
  • 反之,你只需要使用位掩码:result &amp; 0xff000000 产生array[0]result &amp; 0x00ff0000 产生array[1] 等等。
【解决方案4】:
array = [1,2,3,4]
new = []
for number in array:
    bits = bin(number).split('b')[1]
    #transform your number into a binary number (like 0b001), transforms that binary into an array split at b, so [0, 001] and takes the second number of that.
    while len(bits) < 8:
        bits = '0' + bits
        #turns the newly created binary number into an 8 number one
    new.append(bits)
output = '0b'
for item in new:
    output += item
    #puts all the binary's together to form a new, 32 bit binary
output = int(output, 2)
#turns the binary string an integer

为此使用字符串可能不是最干净的方法,但它确实有效。

【讨论】:

    【解决方案5】:

    如果你喜欢一行

    >>> int("".join([bin(x)[2:].zfill(8) for x in a]),2)
    16909060
    

    或者一步一步

    步骤 1. 将数字转换为二进制字符串,例如 0bs

    >>> a  = [1,2,3,4]
    >>> b = [bin(x)[2:] for x in a]
    >>> b
    ['1', '10', '11', '100']
    

    步骤 2. 用零填充元素 (zfill)

    >>> c = [i.zfill(8) for i in b]
    >>> c
    ['00000001', '00000010', '00000011', '00000100']
    

    步骤 3. 连接元素以创建新字符串

    >>> d = "".join(c)
    >>> d
    '00000001000000100000001100000100'
    

    步骤 4. 转换为 10 基数

    >>> int(d,2)
    16909060
    

    【讨论】:

    • 与@Gord 的回答一样低效。
    • @iced 我在戈德的回答下阅读了您的评论。对于一般方法,您是对的 - 如果您正在处理位,您应该使用位方法。但是在这种情况下(对于 256 以下的数字(两种解决方案都限制在这个范围内),无论您使用哪一个。两者都需要相同的时间来吐出结果。我的代码就相当于说“嘿,伙计你也可以使用这个”,仅此而已 :) 顺便说一句,我是哲学研究员,不是软件工程师 :)
    猜你喜欢
    • 2018-09-02
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 2013-04-03
    • 2014-05-08
    • 2018-05-06
    • 2011-02-02
    • 2019-12-13
    相关资源
    最近更新 更多