16進整数のリストが与えられたとき、整数が最上位から最下位まで扱われるような16進整数を最終的に作りたい。
たとえば、次のような場合です。 [0x1A, 0xF3, 0x74, 0xA3] とします。
...私は、最終的に 0x1AF374A3
私が知っている別のプログラミング言語では、これは "join" と呼ばれるかなり単純な操作ですが、どうやら "join" は 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を超える場合は, b.to_bytes(1,'big')
により,論理的に OverflowError: int too big to convert
というエラーが発生することに注意しましょう.もちろん,このようなケースが起こりうる場合は,例外を管理することで改善することができます.
最後に、たった1行で実現できることを示すために、256の累乗を使った解決策も提案させていただきます。
myList = [0x1A, 0xF3, 0x74, 0xA3]
a = sum(nb*(256**i) for i,nb in enumerate(reversed(myList)))
print(hex(a)) # 0x1af374a3
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']