0

I have couple of questions

Say I have a numpy array

a = np.array([0,1,2,3,4,31])

a0 = a[0]
a1 = a[1]
a2 = a[2]
a3 = a[3]
a4 = a[4]
a5 = a[5]


print hex(a4), hex(a5)

gives me

   0x4L 0x1F

same for a0, a1, a2, a3,a5. I know the L is because of the numpy array.

Now how would I get 0x04 and not 0x4.

My required outcome is

'0x1F0403020100'

My required answer should start with 0x -- the hex values of a5, a4, a3, a2, a1, a0 - without the OX. The required output is a string. I can do the bit manipulation, if I have the zero. But not without it.

4
  • Maybe it's just me, but I find your question very unclear on multiple points. Is 0x0403020100 supposed to be hex for your entire array? That most certainly doesn't work like that... That number is 17230332160... And 0x4, 0x04, 0x000004 are all the same number: 4 (in both hexadecimal end decimal). You might be facing an XY problem. Commented Sep 2, 2016 at 21:21
  • Edited the question Commented Sep 2, 2016 at 21:23
  • May I ask why you want to put the hex values of multiple numbers next to each other, after a single 0x? I'm pretty sure you don't need that. I mean, it's as if you wanted to represent your array in decimal as 43210. Commented Sep 2, 2016 at 21:25
  • I am writing a GUI application where I am interacting with an MCU through serial communication. The person who coded the MCU, declared a variable in that format. So when I read from MCU, I read the data as I pointed out in the question, Now I have to display in the required format. Commented Sep 2, 2016 at 21:27

4 Answers 4

3

tl;dr

("0x" + ("{:0>2x}" * len(a))).format(*tuple(a[::-1]))


Explanation:

  • Multiply string "{:0>2x}" a number of times equal to len(a), i.e. do "{:0>2x}" * len(a). This will create the following string:

    '{:0>2x}{:0>2x}{:0>2x}{:0>2x}{:0>2x}{:0>2x}'
    

    {:0>2x} used inside a string can later be formated using the .format method, resulting in a translation of an int into a hexadecimal string, of width 2, where any padding is done with 0.
    Multiplying by the length of the array means you can create that many hex-formatted arguments.

  • Concatenate / prefix this string by "0x"
  • Reverse your array, since you want it reversed, by doing a[::-1]
  • Put the reversed array into a tuple, i.e. tuple(a[::-1]).
  • Expand this tuple using * syntax to make it into method arguments, i.e. *tuple(a[::-1])
  • Now you can use the expanded tuple as an argument to the .format method, on the concatenated string you created containing the custom formatting the correct number of times.

Result:

>>> ("0x" + ("{:0>2x}" * len(a))).format(*tuple(a[::-1]))
'0x1f0403020100'

PS. If you prefer capital hex strings, replace x with X, i.e.:

>>> ("0x" + ("{:0>2X}" * len(a))).format(*tuple(a[::-1]))
'0x1F0403020100'
2
  • Hahahah. In my defense, it's just that python can be ugly this way sometimes :p Commented Sep 2, 2016 at 22:08
  • 1
    @AndrasDeak though, now that you said it, I am itching to remove all spaces from that line ... xD Commented Sep 2, 2016 at 22:11
2

What you really want to do is to store your array in a single number by shifting each element of the array by a certain (8) amount of bits:

>>> a = np.array([0,1,2,3,4,31])
>>> hex(sum([ai*256**i for i,ai in enumerate(a)]))
'0x1f0403020100'

But for this to work, you need to be sure that your array elements are at most 255. That's entirely up to you to keep/check. You should consider using an ndarray of dtype np.uint8, that way there's no chance for you to mangle up the data in your array (since you can't have overflow in your array).

2
  • 1
    It did not work. The answer I got after executing your code is 0xb900L. I am using Python 2.7 Commented Sep 2, 2016 at 21:39
  • @Josh on python 2.7.6 I get '0x1f0403020100L'. Are you sure you copied it properly? Commented Sep 2, 2016 at 21:42
2

You can try this workaround. An element wise hex conversion and a later join. '0x' is added to the start of the string:

>>> a = np.array([0,1,2,3,4,31])
>>> '0x' + ''.join('{:02X}'.format(i) for i in reversed(a))
'0x1F0403020100'
1

For python 3.5+:

'0x'+a.astype(np.uint8)[::-1].tobytes().hex().upper()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.