如果我有一个列表:
["a1", "b1", "c1", "a2", "b2", "c2", "a3", "b3", "c3"]
,我想创建一个新列表,例如:
["a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3"]
我正在尝试在for循环中执行此操作,以便依次添加到新列表:
newlist = []
for i in oldlist:
newlist.append(oldlist[i])
newlist.append(oldlist[2*i])
newlist.append(oldlist[3*i])
i+3
我的代码的问题在于,它将一口气地附加所有i
或i*3
的值,而不是让我的每个第n
版都有机会。 / p>
答案 0 :(得分:5)
您可以跨步使用所需的偏移量序列,可以使用itertools
展平到一维列表中。
>>> import itertools
>>> d = ['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'a3', 'b3', 'c3']
>>> list(itertools.chain.from_iterable([d[::3], d[1::3], d[2::3]]))
['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
您还可以使用numpy
通过对数组进行重塑,转置然后再次展平来进行类似的操作
>>> import numpy as np
>>> d = np.array(['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'a3', 'b3', 'c3'])
>>> np.reshape(d, (d.size//3, 3)).T.flatten()
array(['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'], dtype='<U2')
答案 1 :(得分:2)
假设您希望间隔为n = 3
>>> a=[1,2,3,11,22,33,111,222,333]
>>> res=[]
>>> n=3
>>> for i in range(0,n):
... for z in a[i::n]:
... res.append(z)
...
>>>
>>> res
[1, 11, 111, 2, 22, 222, 3, 33, 333]
更多pythonic
>>> a=['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'a3', 'b3', 'c3']
>>> res = [val for i in range(3) for val in a[i::3]]
>>> res
['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
其中a[i::3]
仅以3的步长从ith索引开始遍历列表。
答案 2 :(得分:0)
zip
的一个有趣的功能是可以将输入分组为固定长度的组,而无需显式切片。 The grouper
recipe使您可以转换为固定长度的组,然后可以将其解压缩以进行另一轮zip
的打包,以便将每个组的前几个元素配对:
>>> lst = ["a1", "b1", "c1", "a2", "b2", "c2", "a3", "b3", "c3", 'a4', 'b4', 'c4'] # Added three more elements so it's clear it's three groups of four, three of three being harder to see
>>> list(zip(*[iter(lst)]*3)) # Grouped sequentially so a is first element of each group
[('a1', 'b1', 'c1'),
('a2', 'b2', 'c2'),
('a3', 'b3', 'c3'),
('a4', 'b4', 'c4')]
>>> list(zip(*zip(*[iter(lst)]*3))) # Unpack and zip again to group a's with a's, b's with b's, etc.
[('a1', 'a2', 'a3', 'a4'), ('b1', 'b2', 'b3', 'b4'), ('c1', 'c2', 'c3', 'c4')]
>>> from itertools import chain
>>> list(chain.from_iterable(zip(*zip(*[iter(lst)]*3)))) # Flatten out to single list
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']
您可以通过以下方式获得相同的结果:
>>> list(chain.from_iterable(lst[i::3] for i in range(3)))
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']
multi-zip
只是将所有工作推到内置函数中(根本没有Python级别的循环)。再加上后者要长两个完整字符,似乎与CoryKramer的答案太相似。 :-)就是说,如果您输入的内容长度不均匀,则后者更为优越;当最短的可迭代数用尽时,zip
停止迭代,而itertools.zip_longest
必须使用填充值。实际切片和展平可避免该问题。