繁体   English   中英

如何将整数列表加入一个整数python

[英]How to join list of integers into one integer python

给定一个十六进制整数列表,我想以一个十六进制整数结束,其中整数被视为最重要的第一个和最不重要的最后一个。

例如,给定... [0x1A, 0xF3, 0x74, 0xA3]

...我想以 0x1AF374A3 结尾

在我熟悉的另一种编程语言中,这是一个相当简单的操作,称为“连接”,但显然“连接”在 Python 中有其他含义。

我知道我可以遍历列表,将每个后续元素乘以 2^something 并将它们相加。 我也知道我可以将元素转换为字符串,连接它们,然后再转换回整数。 但这两种方法似乎都很笨拙。 似乎应该有一种更简单/更优雅的方式。 在那儿?

在此先感谢您的帮助!

我建议您将值切换为bytes类型以便将它们连接起来,它们切换回int类型,如下所示:

myList = [0x1A, 0xF3, 0x74, 0xA3]
# Conversion to 'bytes'
a = bytes()
for b in myList:
    a += b.to_bytes(1,'big')
# Conversion back to 'int'
a = int.from_bytes(a, 'big')
print(hex(a))  # 0x1af374a3

您可以将经典的 for 循环替换为作为参数传递给join()方法的生成器理解,以便连接字节项。 它仍然是可读的,并且更短一些,如下所示:

myList = [0x1A, 0xF3, 0x74, 0xA3]
a = b''.join(b.to_bytes(1,'big') for b in myList) # Conversion to 'bytes'
a = int.from_bytes(a, 'big')                      # Conversion back to 'int'
print(hex(a))  # 0x1af374a3

请注意,如果输入列表中的整数超过 255,那么逻辑上您会收到错误OverflowError: int too big to convert due to b.to_bytes(1,'big') 当然,如果这种情况发生,可以通过管理异常来改进。

最后,我可能还会建议您使用 256 的幂乘法的解决方案,只是为了向您展示它可以仅在一行中实现:

myList = [0x1A, 0xF3, 0x74, 0xA3]
a = sum(nb*(256**i) for i,nb in enumerate(reversed(myList)))
print(hex(a))  # 0x1af374a3
l = [0x1A, 0xF3, 0x74, 0xA3]

merged = ''.join([str(hex(el))[2:] for el in l])

如果你需要十六进制,你可以得到它:

hex(int(merged, 16)) --> 0x1af374a3

以下代码中没有任何极度低效或丑陋的地方,尽管乍一看可能如此。 如果您需要更快的速度,则必须使用按位运算符将所有整数组合在一起。

l = [0x1A, 0xF3, 0x74, 0xA3]
i = int("".join(hex(x)[2:] for x in l), 16)
# And to get the hex representation as requested:
print(hex(i).upper())

还有另一种方法可以通过使用如下字符串格式来利用其中的不良字符串:

i = int(len(l)*"%x" % tuple(l), 16)
print(hex(i))
from functools import reduce
reduce(lambda x, y: x<<8 | y, [0x1A, 0xF3, 0x74, 0xA3])
# 452162723
'0x{:X}'.format(452162723)
# '0x1AF374A3'

相反:

>>> [0x1AF374A3 >> i & 0xff for i in reversed(range(0, 32, 8))]
[26, 243, 116, 163]
>>> [hex(0x1AF374A3 >> i & 0xff) for i in reversed(range(0, 32, 8))]
['0x1a', '0xf3', '0x74', '0xa3']
mylist =[0x1A, 0xF3, 0x74, 0xA3]

most_significant = str(hex(max(mylist)))
print(most_significant + ''.join([str(el).replace('0x', '') for el in mylist if el != max(mylist)]))

0xf326116163

您可以将每个转换为十进制,然后再转换回十六进制,但删除 0x,将它们连接在一起,然后在开头添加 0x。 format()擅长做这样的转换。

mylist = [0x1A, 0xF3, 0x74, 0xA3]
result = '0x' + ''.join([format(int(n), 'x')for n in [format(i , 'd') for i in mylist]])

输出:

'0x1af374a3'

我认为有一种干净且“pythonic”的方法可以使用 Python bytearray类型来解决这个问题:

foolist = [0x1A, 0xF3, 0x74, 0xA3]
# convert to bytearray and then to a single integer in one line:
x = int.from_bytes(bytearray(foolist), "big")
print(hex(x))
# '0x1af374a3'

如果列表中最重要的字节位于列表末尾,请在int.from_bytes函数中使用参数"little"而不是"big"

如果您的列表包含大于 255 的整数,将引发ValueError异常:

>>> foolist1 = [0xFF, 255]                                                                                 

>>> bytearray(foolist1)                                                                                    
bytearray(b'\xff\xff')


>>> foolist2 = [0xFF, 256]                                                                                 

>>> bytearray(foolist2)                                                                                    
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: byte must be in range(0, 256)

byte must be in range(0, 256)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM