[英]Insert items from list to another list every n positions
我有以下清单。
vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
inserted_elements = [2, 2, 2, 2, 2]
我想通过插入每两个元素来获得以下内容。
output = [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]
不仅 Python 列表而且使用 numpy 数组的答案也很好。
我不认为有一种简单的 NumPy 方法可以对任何可能大小的数组执行此操作,但这里有一种使用迭代器和列表理解来执行此操作的 Python 方法:
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]
在输出的每个第三元素将来自it2
,对于迭代器inserted_elements
。 其余的来自it1
对应于vector
。
numpy 数组步骤:
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])
传统的for循环的做法可能会像下面这样,当你随意从2元vector
,并从1元inserted_elements
,使output
列表
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)
列表理解中的相同内容将是
output = [ v for idx in range(0,len(vector),2) for v in vector[idx:idx+2] + [inserted_elements[int(idx/2)]]]
输出将是
[1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]
这是一种有点晦涩的方法 - 但它比其他任何方法都快(到目前为止):
list(itertools.chain(*zip(*[iter(vector)]*2+[iter(inserted_elements)])))
它使用“惯用语”来获取大小为 n 组的项目, [iter(alist)]*n
和itertools.chain
作为展平嵌套列表的一种方式。
已删除的答案使用np.insert
。 为此,我相信insert
使用掩码,如下所示:
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
np.append
答案的一个变体是:
np.column_stack((np.reshape(vector,(-1,2)), inserted_elements)).ravel()
我通常不喜欢np.append
,因为它经常被滥用,尤其是在循环中。 为此,没关系,但我认为column_stack
更干净。
===
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)]
这是一种基于itertools
的方法,它也适用于从一个列表插入到另一个列表的任意数量的元素。 为此,我定义了一个生成器函数,它将把l2
元素插入到l1
每i
项目:
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
这是通过使用itertools.islice
在每次迭代中从迭代器l1
产生最多i
项目来实现的。 使用yield from
我们产生的项目与切片可迭代中的项目一样多,因此可迭代运行到耗尽,( for v in g: yield v
的快捷方式for v in g: yield v
)。
最后,我们可以用try
/ expect
来包装yield
语句以捕获StopIteration
警告。
让我们尝试使用建议的示例:
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]
如果我们想每 3 个项目添加一个l2
项目:
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]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.