I would like to construct list x
from two lists y
and z
. I want all elements from y
be placed where ypos
elements point. For example:
y = [11, 13, 15] z = [12, 14] ypos = [1, 3, 5]
So, x
must be [11, 12, 13, 14, 15]
Another example:
y = [77] z = [35, 58, 74] ypos = [3]
So, x
must be [35, 58, 77, 74]
I've written function that does what I want but it looks ugly:
def func(y, z, ypos): x = [0] * (len(y) + len(z)) zpos = list(range(len(y) + len(z))) for i, j in zip(y, ypos): x[j-1] = i zpos.remove(j-1) for i, j in zip(z, zpos): x[j] = i return x
How to write it in pythonic way?
Straightforward way is to run two nested loops – outer loop gives one sublist of lists, and inner loop gives one element of sublist at a time. Each element is appended to flat list object.
If the lists are very long, repeatedly calling insert
might not be very efficient. Alternatively, you could create two iterators
from the lists and construct a list by getting the next
element from either of the iterators depending on whether the current index is in ypos
(or a set
thereof):
>>> ity = iter(y) >>> itz = iter(z) >>> syp = set(ypos) >>> [next(ity if i+1 in syp else itz) for i in range(len(y)+len(z))] [11, 12, 13, 14, 15]
Note: this will insert the elements from y
in the order they appear in y
itself, i.e. the first element of y
is inserted at the lowest index in ypos
, not necessarily at the first index in ypos
. If the elements of y
should be inserted at the index of the corresponding element of ypos
, then either ypos
has to be in ascending order (i.e. the first index of ypos
is also the lowest), or the iterator of y
has to be sorted by the same order as the indices in ypos
(afterwards, ypos
itself does not have to be sorted, as we are turning it into a set
anyway).
>>> ypos = [5,3,1] # y and z being same as above >>> ity = iter(e for i, e in sorted(zip(ypos, y))) >>> [next(ity if i+1 in syp else itz) for i in range(len(y)+len(z))] [15, 12, 13, 14, 11]
You should use list.insert
, this is what it was made for!
def func(y, z, ypos): x = z[:] for pos, val in zip(ypos, y): x.insert(pos-1, val) return x
and a test:
>>> func([11, 13, 15], [12, 14], [1,3,5]) [11, 12, 13, 14, 15]
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