0

Possible Duplicate:
How do you split a list into evenly sized chunks in Python?
What is the most “pythonic” way to iterate over a list in chunks?

Say I have a string

s = '1234567890ABCDEF'

How can I slice (or maybe split is the correct term?) this string into a list consisting of strings containing 2 characters each?

desired_result = ['12', '34', '56', '78', '90', 'AB', 'CD', 'EF']

Not sure if this is relevant, but I'm parsing a string of hex characters and the final result I need is a list of bytes, created from the list above (for instance, by using int(desired_result[i], 16))

Community
  • 1
  • 1
Praetorian
  • 106,671
  • 19
  • 240
  • 328

4 Answers4

6
3>> bytes.fromhex('1234567890ABCDEF')
b'\x124Vx\x90\xab\xcd\xef'
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • I always forget about `fromhex` in Py 3.x - nice one +1 – Jon Clements Jan 01 '13 at 03:12
  • TIL that it has a name and it's called X-Y :) – miku Jan 01 '13 at 03:14
  • `bytes.fromhex` works great! But is there a way to convert 4 (and 8) characters at a time? Something like `words.fromhex` and `long.fromhex`? – Praetorian Jan 01 '13 at 03:28
  • @Praetorian Take the result of your byte string - then use `struct.unpack` - Ignacio: my apologies for a not so great edit – Jon Clements Jan 01 '13 at 03:31
  • @Jon: No worries, it happens. – Ignacio Vazquez-Abrams Jan 01 '13 at 03:38
  • @Jon Ok, I can't figure this. `struct.unpack` works, but it needs the bytes array argument to contain the exact number of bytes required by the format argument. I want `struct.unpack` to return an array of words (or longs) taking 4 (or 8) bytes at a time. Is that possible? – Praetorian Jan 01 '13 at 04:11
  • @Praetorian sure - but that's another question isn't it... We've already make an assumption about your X-Y question - now you throw in another twist. Feel free to post a new question - detailing your *exact* requirements – Jon Clements Jan 01 '13 at 04:14
3

You could use binascii:

>>> from binascii import unhexlify
>>> unhexlify(s)
'\x124Vx\x90\xab\xcd\xef'

Then:

>>> list(_)
['\x12', '4', 'V', 'x', '\x90', '\xab', '\xcd', '\xef']
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
3
>>> s = '1234567890ABCDEF'
>>> iter_s = iter(s)
>>> [a + next(iter_s) for a in iter_s]
['12', '34', '56', '78', '90', 'AB', 'CD', 'EF']
>>>
Rusty Rob
  • 16,489
  • 8
  • 100
  • 116
0
>>> s = '1234567890ABCDEF'
>>> [char0+char1 for (char0, char1) in zip(s[::2], s[1::2])]
['12', '34', '56', '78', '90', 'AB', 'CD', 'EF']

But, as others have noted, there are more direct solutions to the more general problem of converting hexadecimal numbers to bytes. Also note that Robert Kings's solution is more efficient, in general, as it essentially has a zero memory footprint (at the cost of a less legible code).

Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260