找到连续的组合

时间:2012-06-10 19:32:52

标签: python combinations

  

可能重复:
  Rolling or sliding window iterator in Python

我是编程新手,也在学习Python。我正在寻找一种解决问题的有效/ pythonic方式。

我想要一个函数,它返回一个包含父迭代组合的迭代列表,只要组合中的元素与原始父迭代的连续顺序相同。

我不确定“连续”是否将这个概念描述为“连续”的正确词语通常意味着“重复相同的元素”。例如[1,1,1],'aaa'等......

我的意思是给定列表[1,2,3,4,5]:

[1,2,3]是连续的,但[1,2,4]不是。 (这是否有一个词?)

这是我创建的函数consecutive_combinations()和预期的行为:

def consecutive_combinations(iterable, consec):
    begin = 0
    chunks = len(iterable) + 1 - consec
    return [iterable[x + begin: x + consec] for x in xrange(chunks)]

def test():
    t = (1,2,3,4,5)
    s = "The quick brown fox jumps over the lazy dog."
    CC = consecutive_combinations
    assert CC(t, 2) == [(1, 2), (2, 3), (3, 4), (4, 5)]
    assert CC(t, 3) == [(1, 2, 3), (2, 3, 4), (3, 4, 5)]
    assert CC(t, 4) == [(1, 2, 3, 4), (2, 3, 4, 5)]
    assert CC(t, 5) == [(1, 2, 3, 4, 5)]
    assert CC(s, 3) == ['The', 'he ', 'e q', ' qu', 'qui', 'uic', 'ick', 'ck ', 'k b', ' br', 'bro', 'row', 'own', 'wn ', 'n f', ' fo', 'fox', 'ox ', 'x j', '  ju', 'jum', 'ump', 'mps', 'ps ', 's o', ' ov', 'ove', 'ver', 'er ', 'r t', '    th', 'the', 'he ', 'e l', ' la', 'laz', 'azy', 'zy ', 'y d', ' do', 'dog', 'og. ']
    assert CC('', 3) == []
    print "All tests passed!"

test()

这是一种有效的解决方案吗?在itertools或其他预先构建的模块中有什么东西可以做这种事吗?

2 个答案:

答案 0 :(得分:5)

我喜欢实用的zip方法:

n = 3
s = "The quick brown fox jumps over the lazy dog."
zip(*(s[i:] for i in xrange(n)))

它不是超级高效的,它只适用于序列,但通常足以完成工作。

相应的itertools解决方案是对上述内容的非常简单的转换:

from itertools import izip, islice, tee

def slices(iterable, n):
    return izip(*(islice(it, i, None) for i, it in enumerate(tee(iterable, n))))

很多i s ...

尽管如此,这个应该适用于任何迭代(但对于像列表或字符串这样的普通序列可能会更慢)。

答案 1 :(得分:3)

你的解决方案很好。但是你可以稍微缩短它。例如:

def subsequences(iterable, length):
    return [iterable[i: i + length] for i in xrange(len(iterable) - length + 1)]