Working with Collections
Recall that zip() truncates the sequence at the shortest list. This means that, if the
list is not an even multiple of the grouping factor n, (len(flat)%n != 0), which
is the final slice, won't be the same length as the others and the others will all be
truncated. This is rarely what we want.
If we use the itertools.zip_longest() method, then we'll see that the final tuple
will be padded with enough None values to make it have a length of n. In some cases,
this padding is acceptable. In other cases, the extra values are undesirable.
The list slicing approach to grouping data is another way to approach the problem
of structuring a flat sequence of data into blocks. As it is a general solution, it doesn't
seem to offer too many advantages over the functions in the previous section. As a
solution specialized for making two tuples from a flat last, it's elegantly simple.
Using reversed() to change the order
There are times when we need a sequence reversed. Python offers us two approaches
to this: the reversed() function and slices with reversed indices.
For an example, consider performing a base conversion to hexadecimal or binary.
The following is a simple conversion function:
def digits(x, b):
if x == 0: return
yield x % b
for d in to_base(x//b, b):
yield d
This function uses a recursion to yield the digits from the least significant to the most
significant. The value of x%b will be the least significant digits of x in the base b.
We can formalize it as following:
()
()
[]
0
digits ,
mod digits , 0
x
xb x
xb b x
b
=
=
+ >
if
if
In many cases, we'd prefer the digits to be yielded in the reverse order. We can wrap
this function with the reversed() function to swap the order of the digits:
def to_base(x, b):
return reversed(tuple(digits(x, b)))