Given a list
a = [0,1,2,3,4,5,6,7,8,9]
how can I get
b = [0,9,1,8,2,7,3,6,4,5]
That is, produce a new list in which each successive element is alternately taken from the two sides of the original list?
You can use the zip() function to join lists together. The zip() function will iterate tuples with the corresponding elements from each of the lists, which you can then format as Michael Butscher suggested in the comments. Finally, just join() them together with newlines and you have the string you want.
>>> [a[-i//2] if i % 2 else a[i//2] for i in range(len(a))] [0, 9, 1, 8, 2, 7, 3, 6, 4, 5]
Explanation:
This code picks numbers from the beginning (a[i//2]
) and from the end (a[-i//2]
) of a
, alternatingly (if i%2 else
). A total of len(a)
numbers are picked, so this produces no ill effects even if len(a)
is odd.[-i//2 for i in range(len(a))]
yields 0, -1, -1, -2, -2, -3, -3, -4, -4, -5
,[ i//2 for i in range(len(a))]
yields 0, 0, 1, 1, 2, 2, 3, 3, 4, 4
,
and i%2
alternates between False
and True
,
so the indices we extract from a
are: 0, -1, 1, -2, 2, -3, 3, -4, 4, -5
.
My assessment of pythonicness:
The nice thing about this one-liner is that it's short and shows symmetry (+i//2
and -i//2
).
The bad thing, though, is that this symmetry is deceptive:
One might think that -i//2
were the same as i//2
with the sign flipped. But in Python, integer division returns the floor of the result instead of truncating towards zero. So -1//2 == -1
.
Also, I find accessing list elements by index less pythonic than iteration.
cycle
between getting items from the forward iter
and the reversed
one. Just make sure you stop at len(a)
with islice
.
from itertools import islice, cycle iters = cycle((iter(a), reversed(a))) b = [next(it) for it in islice(iters, len(a))] >>> b [0, 9, 1, 8, 2, 7, 3, 6, 4, 5]
This can easily be put into a single line but then it becomes much more difficult to read:
[next(it) for it in islice(cycle((iter(a),reversed(a))),len(a))]
Putting it in one line would also prevent you from using the other half of the iterators if you wanted to:
>>> iters = cycle((iter(a), reversed(a))) >>> [next(it) for it in islice(iters, len(a))] [0, 9, 1, 8, 2, 7, 3, 6, 4, 5] >>> [next(it) for it in islice(iters, len(a))] [5, 4, 6, 3, 7, 2, 8, 1, 9, 0]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With