簡體   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