在Python3.x中通过切片操作列表



有没有办法每隔几项对列表进行切片,然后反转它们
例如,我可以转动:吗

1 2 3 4 5 6 7 8 9

进入:

7 8 9 4 5 6 1 2 3

有没有一个简单的切片表示法可以实现这个目标,类似于用于反转列表的list[::-1]?

没有切片表示法,以下是我可能会做的操作(这是使用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配方和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方法中,您只需要在import语句和grouper函数内部用zip_longest替换izip_longest

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个相等的部分时,此解决方案才有效。

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"

最新更新