4

如果不是,那么函数的规范名称?“循环”对我来说是有意义的,但这是采取的。

标题中的示例是为了清晰和简洁而编写的。我正在处理的真实案例有很多重复。(例如,我希望 [1, 1, 0, 0, 0, 2, 1] “匹配” [0, 0, 2, 1, 1, 1, 0])

这类事情模糊了我的算法,并用其他无用的重复填充我的代码。

4

3 回答 3

8

您可以通过以下方式获取列表的周期:

def cycles(a):
    return [ a[i:] + a[:i] for i in range(len(a)) ]

然后,您可以检查 b 是否是 a 的循环:

b in cycles(a)

如果列表的长度很长,或者如果想要对相同的循环进行多次比较,则将结果嵌入到集合中可能是有益的(在性能方面)。

set_cycles = set(cycles(a))
b in set_cycles

您可以通过在列表中嵌入相等性检查并使用任何方法来防止构造所有循环:

any( b == a[i:]+a[:i] for i in range(len(a)))

您也可以通过将cycles函数转换为生成器来实现此效果。

于 2012-11-21T16:04:22.187 回答
5

之前误解了你的问题。如果您想检查列表的任何循环是否与列表l1匹配l2,最好(最干净/最 Pythonic)的方法可能是any(l1 == l2[i:] + l2[:i] for i in xrange(len(l2))). 还有一种rotate方法collections.deque可能对您有用。

于 2012-11-21T16:03:11.410 回答
0

您可以使用cyclefrom itertools以及islice将其剪切。这基本上将这个答案放在列表理解中,因此列表为每个元素移动一次。

>>> from itertools import islice, cycle
>>> l = [0,1,2]
>>> [tuple(islice(cycle(t),i,i+len(t))) for i,_ in enumerate(l)]
[(0, 1, 2), (1, 2, 0), (2, 0, 1)]
于 2012-11-21T16:31:24.930 回答