问题
I have the following list.
vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
inserted_elements = [2, 2, 2, 2, 2]
I want to get the following by inserting every two elements.
output = [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]
Not only the Python list but also the answer using numpy array is fine.
回答1:
Here's an itertools based approach, which also works for an arbitrary number of elements to be inserted from one list to the other. For this I've defined a generator function, which will insert and element from l2
into l1
every i
items:
def insert_every_n(l1, l2, k):
i1, i2 = iter(l1), iter(l2)
while True:
try:
yield from islice(i1, k)
yield next(i2)
except StopIteration:
return
This works by yielding up to i
items from the iterator l1
on each iteration by using itertools.islice. With yield from we are yielding as many items as there are in the sliced iterable, so the iterable is run to exhaustion, (a shortcut for for v in g: yield v
).
Finally we can wrap the yield
statements with a try
/expect
to catch the StopIteration
warning.
Let's try with the proposed example:
vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
inserted_elements = [2, 2, 2, 2, 2]
list(insert_every_n(vector, inserted_elements, k=2))
# [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]
And if we wanted to add an item of l2
every 3 items:
vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
inserted_elements = [2, 2, 2, 2]
list(insert_every_n(vector, inserted_elements, k=3))
# [1, 2, 3, 2, 4, 5, 6, 2, 7, 8, 9, 2, 10, 2]
回答2:
numpy array step:
1.
>>> a=np.reshape(np.matrix([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),(5, 2))
>>> a
matrix([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10]])
2.
>>> b=np.reshape(np.matrix([2, 2, 2, 2, 2]),(5, 1))
>>> b
matrix([[2],
[2],
[2],
[2],
[2]])
3.
>>> M = np.append(a, b, axis=1)
>>> M
matrix([[ 1, 2, 2],
[ 3, 4, 2],
[ 5, 6, 2],
[ 7, 8, 2],
[ 9, 10, 2]])
4.
>>> result=np.array(M).flatten()
>>> result
array([ 1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2])
回答3:
A traditional for-loop approach might look like as follows, where you pick 2 elements from vector
and 1 element from inserted_elements
and make the output
list
vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
inserted_elements = [2, 2, 2, 2, 2]
output = []
#Pick two elements from vector and one element from inserted_elements and add it to output list
for idx in range(0,len(vector),2):
output.extend(vector[idx:idx+2] + [inserted_elements[int(idx/2)]])
print(output)
The same thing in list-comprehension will be
output = [ v for idx in range(0,len(vector),2) for v in vector[idx:idx+2] + [inserted_elements[int(idx/2)]]]
The output will be
[1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]
回答4:
Here's a somewhat obscure approach - but it's faster than anything else (so far):
list(itertools.chain(*zip(*[iter(vector)]*2+[iter(inserted_elements)])))
It uses a 'idiom' for taking items in size n groups, [iter(alist)]*n
, and itertools.chain
as a way of flattening a nested list.
A deleted answer used np.insert
. For this I believe insert
uses masking as demonstrated below:
def foo(vector, inserted_elements):
res = np.zeros(len(vector)+len(inserted_elements),int)
mask = res.astype(bool)
mask[2::3]=True
res[mask]=inserted_elements
res[~mask]=vector
return res
A variation on the np.append
answer is:
np.column_stack((np.reshape(vector,(-1,2)), inserted_elements)).ravel()
I generally don't like np.append
, since it is often misused, especially in loops. For this it's ok, but I think column_stack
is cleaner.
===
In [254]: list(zip(*[iter(vector)]*2+[iter(inserted_elements)]))
Out[254]: [(1, 2, 2), (3, 4, 2), (5, 6, 2), (7, 8, 2), (9, 10, 2)]
回答5:
I don't think there's an easy NumPy way to do this for any possible size of arrays, but here's a python way of doing so using iterators and list comprehension:
it1, it2 = map(iter, (vector, inserted_elements))
n = sum(map(len, (vector, inserted_elements)))
[next(it2) if i % 3 == 0 else next(it1) for i in range(1, n+1)]
# [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]
Every 3rd element in the output will come from it2
, the iterator for inserted_elements
. The rest come from it1
which corresponds to vector
.
来源:https://stackoverflow.com/questions/56286403/insert-items-from-list-to-another-list-every-n-positions