Как объединить список целых чисел в один целочисленный питон - PullRequest
0 голосов
/ 24 августа 2018

Учитывая список шестнадцатеричных целых чисел, я хочу закончить одним шестнадцатеричным целым числом, где целые числа обрабатываются как наиболее значимые первые и наименее значимые последние.

Например, учитывая ... [0x1A, 0xF3, 0x74, 0xA3]

... я хочу закончить с 0x1AF374A3

В другом языке программирования, с которым я знаком, это довольно простая операция, называемая «join», но, очевидно, «join» означает что-то еще в Python.

Я знаю, что могу перебирать список, умножая каждый последующий элемент на 2 ^ что-то и добавляя их. Я также знаю, что могу преобразовать элементы в строки, объединить их и затем преобразовать обратно в целое число. Но оба эти подхода кажутся неуклюжими. Кажется, должен быть более простой / более элегантный способ. Есть ли?

Заранее спасибо за любую помощь!

Ответы [ 6 ]

0 голосов
/ 24 августа 2018

В следующем коде нет ничего крайне неэффективного и уродливого, хотя это может показаться на первый взгляд. Если вам нужна еще большая скорость, вам придется использовать побитовые операторы для объединения всех целых.

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))
0 голосов
/ 24 августа 2018

Вы можете преобразовать каждый в десятичную, затем обратно в гекс, но удалить 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'
0 голосов
/ 24 августа 2018
l = [0x1A, 0xF3, 0x74, 0xA3]

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

Если вам нужен гекс, вы можете получить его как:

hex(int(merged, 16)) --> 0x1af374a3
0 голосов
/ 24 августа 2018
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

0 голосов
/ 24 августа 2018

Я предлагаю вам переключить значения на тип байт , чтобы объединить их, а затем переключить обратно на тип 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 из-за 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
0 голосов
/ 24 августа 2018
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']
...