生成器中的循环列表

时间:2017-12-02 00:26:13

标签: python python-3.x

建议s = [1, 2, 3, 4]

如果zip(s, s[1:])返回[(1, 2), (2, 3), (3, 4)]。 是否可以重写zip(s, s[1:])以返回[(1, 2), (2, 3), (3, 4), (4, 1)]

或者为了一般性的缘故,是否可以将列表与自己压缩,以便最后一次为(list[-1], list[0])

4 个答案:

答案 0 :(得分:4)

是的,你可以使用itertools来获得方便的迭代器来实现这一目标:

>>> from itertools import cycle, islice
>>> s = [1, 2, 3, 4]
>>> list(zip(s, islice(cycle(s), 1, None)))
[(1, 2), (2, 3), (3, 4), (4, 1)]

注意,itertools.cycle的工作原理如下:

  

cycle('ABCD') --> A B C D A B C D ...

它是一个无限的迭代器,所以要小心。 zip此处停留时间最短,因此工作正常。

此外,itertools.islice

  

islice('ABCDEFG', 2, None) --> C D E F G

这就像slice或序列切片一样,即my_list[1:] == my_list[1:None] == my_list[slice(1, None)],除了它适用于任何可迭代的,而不仅仅是序列。

无论如何,请注意这种方法是可以推广的:

>>> list(zip(s, islice(cycle(s), 2, None)))
[(1, 3), (2, 4), (3, 1), (4, 2)]
>>> list(zip(s, islice(cycle(s), 3, None)))
[(1, 4), (2, 1), (3, 2), (4, 3)]
>>> list(zip(s, islice(cycle(s), 4, None)))
[(1, 1), (2, 2), (3, 3), (4, 4)]

答案 1 :(得分:2)

import itertools as it


iterable = [1, 2, 3, 4]

c = it.cycle(iterable)
next(c)

list(zip(iterable, c))
# [(1, 2), (2, 3), (3, 4), (4, 1)]

答案 2 :(得分:2)

>>> s = [1, 2, 3, 4]

>>> zip(s, s[1:] + s[:1])
[(1, 2), (2, 3), (3, 4), (4, 1)]

答案 3 :(得分:0)

可以使用参数化切片索引进行纯python循环zip答案,添加切片

s = [1, 2, 3, 4]

n = 2

list(zip(s[n::] + s[0:n], s[n+1::] + s[0:n+1]))
Out[100]: [(3, 4), (4, 1), (1, 2), (2, 3)]

n = 0

list(zip(s[n::] + s[0:n], s[n+1::] + s[0:n+1]))
Out[101]: [(1, 2), (2, 3), (3, 4), (4, 1)]