>>> from itertools import islice, chain
>>> L = ["2H", "AH", "KH", "QH", "JH", "0H", "9H"]
>>> list(chain.from_iterable(
zip(*[islice(reversed(L),i,None) for i in range(j)])
for j in range(3,6)))
[('9H', '0H', 'JH'), ('0H', 'JH', 'QH'), ('JH', 'QH', 'KH'), ('QH', 'KH', 'AH'),
('KH', 'AH', '2H'), ('9H', '0H', 'JH', 'QH'), ('0H', 'JH', 'QH', 'KH'),
('JH', 'QH', 'KH', 'AH'), ('QH', 'KH', 'AH', '2H'), ('9H', '0H', 'JH', 'QH', 'KH'),
('0H', 'JH', 'QH', 'KH', 'AH'), ('JH', 'QH', 'KH', 'AH', '2H')]
说明
此解决方案基于 zip 的使用。
>>> zip(L,L)
[('2H', '2H'), ('AH', 'AH'), ('KH', 'KH'), ('QH', 'QH'), ('JH', 'JH'), ('0H', '0H'), ('9H', '9H')]
这显示了zip 工作原理的示例,通过从其每个参数中获取一个项目。
>>> zip(L,L[1:])
[('2H', 'AH'), ('AH', 'KH'), ('KH', 'QH'), ('QH', 'JH'), ('JH', '0H'), ('0H', '9H')]
从与第二个参数相同的列表的第一个项目开始,您可以获得每 2 个项目。
>>> zip(L,L[1:],L[2:])
[('2H', 'AH', 'KH'), ('AH', 'KH', 'QH'), ('KH', 'QH', 'JH'), ('QH', 'JH', '0H'), ('JH', '0H', '9H')]
每 3 个项目相同。
>>> zip(*[L[i:] for i in range(3)])
[('2H', 'AH', 'KH'), ('AH', 'KH', 'QH'), ('KH', 'QH', 'JH'), ('QH', 'JH', '0H'), ('JH', '0H', '9H')]
要自动执行此操作,您可以使用 * (splat) 从列表解析中获取 zip 的参数。
在示例中,结果是反向的,所以reversed 给出了一个遍历列表的反向迭代器。要对迭代器进行切片,必须使用来自 itertools 的 islice。 islice 采用可迭代对象,后跟索引以开始切片,并以索引结束切片。 None 可用于一直到迭代的末尾。
>>> zip(*[islice(reversed(L),i,None) for i in range(3)])
[('9H', '0H', 'JH'), ('0H', 'JH', 'QH'), ('JH', 'QH', 'KH'), ('QH', 'KH', 'AH'), ('KH', 'AH', '2H')]
这样就给出了每 3 个项目的所有结果。现在需要每 4 和 5 个项目,因此对 range(3)、range(4) 和 range(5) 执行此操作。
(zip(*[islice(reversed(L),i,None) for i in range(j)]) for j in range(3,6))
这将为生成器提供每个3、4 和5 的列表,但它们必须是一个列表。它们可以与chain.from_iterable 链接在一起,结果将转换为list。