Itertools,组合

时间:2014-05-27 00:17:03

标签: python combinations

我有一个问题。我使用组合从列表中获得不同的组合。但是,如果我希望得到更具体的升序(3D,4D,5D)组合,而不是(4D,5D,8D),我该怎么做?

例如:

from itertools import combinations

cards = ["3D", "4D", "5D", "6D"]
comb = []
for j in combinations(cards, 3):
    comb.append(list(j))
for j in combinations(cards, 4)):
    comb.append(list(j))

但我得到的输出如下:

["3D", "4D", "5D"], ["3D", "4D", "6D"], ["3D", "5D", "6D"], ["4D", "5D", "6D"], ["3D", "4D", "5D", "6D"]

如何获得这样的输出?

[["3D", "4D", "5D"], ["4D", "5D", "6D"], ["3D", "4D", "5D", "6D"]]

2 个答案:

答案 0 :(得分:1)

逐步浏览列表并将每个连续3个元素压缩在一起。然后在最后添加完整的卡片列表。

print ([list(t) for t in zip(*(cards[i:] for i in xrange(3)))]+[cards])
[['3D', '4D', '5D'], ['4D', '5D', '6D'], ['3D', '4D', '5D', '6D']]

如果您想在较长的列表和第5组元素上使用它,您可以更改xrange to xrange(5)

cards = ["3D", "4D", "5D", "6D","7D","8D","9D"]
print ([list(t) for t in zip(*(cards[i:] for i in xrange(5)))]+[cards])
[['3D', '4D', '5D', '6D', '7D'], ['4D', '5D', '6D', '7D', '8D'], ['5D', '6D', '7D', '8D', '9D'], ['3D', '4D', '5D', '6D', '7D', '8D', '9D']]

如果您的卡片列表未按排序顺序排列,您可以在list之前调用sort方法zip

cards = ["5D", "6D","3D", "4D"]    
cards.sort()
print [list(t) for t in zip(*(cards[i:] for i in xrange(3)))]+[cards]#
[['3D', '4D', '5D'], ['4D', '5D', '6D'], ['3D', '4D', '5D', '6D']]

答案 1 :(得分:0)

使用以下代码:

from itertools import combinations

def check(lst):
        for i in range(len(lst)):
            try:
                    if lst[i+1]-lst[i] != 1:
                            return False
            except IndexError:
                    pass
        return True

cards = ["3D", "4D", "5D", "6D"]
comb = []
for j in combinations(cards, 3):
    comb.append(list(j))
for j in combinations(cards, 4):
    comb.append(list(j))

subs = []
for i in comb:
        subs.append([int(item[0]) for item in i])

subs = [item for item in subs if check(item) == True]

comb = []

for i in subs:
        comb.append([str(item)+'D' for item in i])

print comb

此代码使用以下代码将每个子列表转换为整数列表:

>>> item = ['3D', '4D', '6D']
>>> [int(val[0]) for val in item]
[3, 4, 6]
>>> 

然后我们确保这些数字直接上升:

>>> def check(lst):
...         for i in range(len(lst)):
...             try:
...                     if lst[i+1]-lst[i] != 1:
...                             return False
...             except IndexError:
...                     pass
...         return True
... 
>>> check([3, 4, 6])
False
>>> check([3, 4, 5])
True
>>> check([3, 4, 5, 6])
True
>>> check([3, 4, 5, 8])
False
>>> 

然后使用上面的逻辑,我们过滤掉所有内容,给出以下内容。

运行:

bash-3.2$ python check.py
[['3D', '4D', '5D'], ['4D', '5D', '6D'], ['3D', '4D', '5D', '6D']]
bash-3.2$