有没有办法每隔几个项目切一个列表然后反转它们? 例如,我可以转:
1 2 3 4 5 6 7 8 9
成:
7 8 9 4 5 6 1 2 3
是否有一个简单的切片符号可以实现这个目标,类似于用于反转列表的list [:: - 1]?
答案 0 :(得分:2)
没有切片表示法,这是我可能会这样做的(这是Python 2.x,Python 3.x代码包含在最后):
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [x for s in reversed(zip(*[iter(lst)]*3)) for x in s]
[7, 8, 9, 4, 5, 6, 1, 2, 3]
将元素聚类到n
长度组的方法直接来自zip
文档,因此这里的方法是创建3个组,反转结果列表,然后使用列表推导扁平化。
或者使用itertools模块,使用grouper
recipe和chain.from_iterable
:
from itertools import izip_longest, chain
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
result = list(chain.from_iterable(reversed(list(grouper(lst, 3)))))
Python 3版本:
对于第一种方法,您需要将zip
返回的生成器转换为列表,否则reversed
将失败:
>>> [x for s in reversed(list(zip(*[iter(lst)]*3))) for x in s]
[7, 8, 9, 4, 5, 6, 1, 2, 3]
在itertools方法中,您只需要在导入语句和izip_longest
函数内部用zip_longest
替换grouper
。
答案 1 :(得分:2)
numpy
可以让您轻松做到这一点:
>>> import numpy as np
>>> a = np.arange(1, 10)
>>> result = a.reshape((3, -1))[::-1].ravel() #if you OK with getting np.array
>>> result
array([7, 8, 9, 4, 5, 6, 1, 2, 3])
如果你想要一个清单
>>> result = a.reshape((3, -1))[::-1].ravel().tolist() #if you want to get back a list
>>> result
[7, 8, 9, 4, 5, 6, 1, 2, 3]
此解决方案仅在列表可以分为n个相等部分时才有效。
答案 2 :(得分:1)
QTYPERGROUP = 3
lst = [1,2,3,4,5,6,7,8,9]
reversed_by_group = [el for sublist in list(reversed(list(zip(*[iter(lst)]*QTYPERGROUP)))) for el in sublist]
# [7, 8, 9, 4, 5, 6, 1, 2, 3]
这很长很难看,但它确实起了作用。请注意,这只适用于len(lst) % QTYPERGROUP == 0
,否则会忽略其余部分。例如
QTYPERGROUP = 4
reversed_by_group = [el for sublist in list(reversed(list(zip(*[iter(lst)]*QTYPERGROUP)))) for el in sublist]
# [5, 6, 7, 8, 1, 2, 3, 4] there's no "9"