I have string of bytes that come from embeded system and I use python struct.unpack()
to give me tuple of values.
As there are a lot of values I wish to make code more readable. For now I have it done like this:
ArrA = [None] * 3
ArrB = [None] * 2
ArrA[0],ArrA[1],ArrA[2], n, ArrB[0],ArrB[1], crc = (1, 2, 3, 4, 5, 6, 7)
# tuple came from unpack()
Result:
ArrA = [1, 2, 3]
n = 4
ArrB = [5, 6]
crc = 7
Is there some way to shorten arrays? eg ArrA[0],ArrA[1],ArrA[2]
to something like ArrA[]*3
??
In example arrays are short in real they are pretty long.
I don't think there's a way to do this with unpacking. If you had only one list, you could use a starred expression*, but not with multiple lists.
Here are some alternatives:
t = (1, 2, 3, 4, 5, 6, 7)
ArrA = list(t[:3])
n = t[3]
ArrB = list(t[4:6])
crc = t[6]
One difference is that you won't get an error if t
is too long, but you can simply add a check, e.g:
assert len(t) == 7, f"Wrong size: {len(t)}"
If you'd rather focus on the number of elements in the lists rather than their positions in t
, you can make t
into an iterator and consume it a chunk at a time:
it = iter(t)
ArrA = [next(it) for _ in range(3)]
n = next(it)
ArrB = [next(it) for _ in range(2)]
crc = next(it)
This lets you check that t
is not too long using this weird syntax:
() = it # Confirm exhausted
Instead of using list comprehensions, islice
is cleaner:
from itertools import islice
ArrA = list(islice(it, 3))
...
ArrB = list(islice(it, 2))
...
Python lists are like stacks, with pops happening from the end by default. So we just need to convert t
to a list and reverse it to be able to use it similarly to the iterator solution above. It's also possible to pop from the start, but it's less efficient at large scales and I think this is cleaner anyway.
L = list(t)[::-1]
ArrA = [L.pop() for _ in range(3)]
n = L.pop()
ArrB = [L.pop() for _ in range(2)]
crc = L.pop()
() = L # Confirm exhausted
* For example:
t = (1, 2, 3, 4, 5, 6, 7)
m, *ArrC, crd = t
Result:
m = 1
ArrC = [2, 3, 4, 5, 6]
crd = 7