获取列表中的所有邻居元素组合

时间:2014-07-01 17:19:14

标签: python list math combinations

是否可以获得所有元素组合,以防它们是邻居? 这是一个例子:

编辑:我想在字符串上使用它,而不仅仅是数字。例如:[Explain,it,to,me,please]

列表:

[0,1,2,3,4]

结果:

[0,1,2,3,4],
[0,1,2,3],
[1,2,3,4],
[0,1,2],
[1,2,3],
[2,3,4],
[0,1],
[1,2],
[2,3],
[3,4],
[0],
[1],
[2],
[3],
[4]

结果中不会有例如[0,2,3]等,因为02不是上面排序列表中的邻居。

我尝试使用itertools.combinations,但它提供了所有组合。

3 个答案:

答案 0 :(得分:9)

你可以这样做:

>>> L = [0,1,2,3,4]
>>> result = [L[i:j] for i in xrange(len(L)) for j in xrange(i + 1, len(L) + 1)]
>>> pprint.pprint(result)
[[0],
 [0, 1],
 [0, 1, 2],
 [0, 1, 2, 3],
 [0, 1, 2, 3, 4],
 [1],
 [1, 2],
 [1, 2, 3],
 [1, 2, 3, 4],
 [2],
 [2, 3],
 [2, 3, 4],
 [3],
 [3, 4],
 [4]]

然后,按降序长度和升序值排序:

>>> result.sort(key=lambda x: (-len(x), x))
>>> pprint.pprint(result)
[[0, 1, 2, 3, 4],
 [0, 1, 2, 3],
 [1, 2, 3, 4],
 [0, 1, 2],
 [1, 2, 3],
 [2, 3, 4],
 [0, 1],
 [1, 2],
 [2, 3],
 [3, 4],
 [0],
 [1],
 [2],
 [3],
 [4]]

对于字符串,它会产生:

>>> L = ['Explain', 'it', 'to', 'me', 'please']
>>> result = [L[i:j] for i in xrange(len(L)) for j in xrange(i + 1, len(L) + 1)]
>>> result.sort(key=lambda x: (-len(x), x))
>>> pprint.pprint(result)
[['Explain', 'it', 'to', 'me', 'please'],
 ['Explain', 'it', 'to', 'me'],
 ['it', 'to', 'me', 'please'],
 ['Explain', 'it', 'to'],
 ['it', 'to', 'me'],
 ['to', 'me', 'please'],
 ['Explain', 'it'],
 ['it', 'to'],
 ['me', 'please'],
 ['to', 'me'],
 ['Explain'],
 ['it'],
 ['me'],
 ['please'],
 ['to']]

答案 1 :(得分:1)

这是使用来自itertools

的旧window配方的一种方法
from itertools import islice

def window(seq, n=2):
    "Returns a sliding window (of width n) over data from the iterable"
    "   s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...                   "
    it = iter(seq)
    result = tuple(islice(it, n))
    if len(result) == n:
        yield result    
    for elem in it:
        result = result[1:] + (elem,)
        yield result

def all_windows(seq):
    for l in xrange(1, len(seq) + 1):
        for w in window(seq, l):
            yield w

答案 2 :(得分:0)

就像cpburnz回答一样,这是通过嵌套列表理解来实现的 不同的是,列表按长度顺序生成,从最大到最小。

[L[j:i+j] for i in xrange(len(L), 0, -1) for j in xrange(len(L) - i + 1)]

但是,如果您只需要生成列表,那么请考虑使用生成器编写更易读的代码:

def all_windows(L):
    for i in xrange(len(L), 0, -1):
        for j in xrange(len(L) - i + 1):
            yield L[j:i+j]

与上面相同的代码,但设计为迭代:

for sublist in all_windows(L):
    # does something with sublist