在python中生成两组与一个列表的组合

时间:2015-04-16 16:54:41

标签: python combinations itertools

假设有9种不同的牌和2种不同的牌手。当9张牌中的每位牌手(共6张牌)给出3张牌时。

如何生成向2名玩家分发6张牌的所有组合?

很容易计算出组合的数量:

number_of_combinations = (9!/(6!*3!)) * (6!/(3!*3!)) = 1680
  • Player1在9张牌中获得3张牌。可能的组合数量为9!/(6!*3!)
  • Player2在剩下的6张牌中获得3张牌。可能的组合数量为6!/(3!*3!)

因此,将6张牌分配给2名玩家的所有组合均为(9!/(6!*3!)) * (6!/(3!*3!)

但是生成组合看起来非常困难;这就是我的尝试:

comb = itertools.combination([1,2,3,4,5,6,7,8,9], 6)

但有一个问题:

假设有两个列表,case1和case2。

case1 = [1,2,3 ,4,5,6]
case2 = [1,2,4 ,3,5,6]

就我而言,我必须采用不同的方式处理case1和case2。

但如果我只生成6种尺寸组合,我就不能这样做。

4 个答案:

答案 0 :(得分:4)

要生成一个处理,您可以使用random.sample() function随机挑选6张卡片;将前3个给予玩家1,剩下的给玩家2:

dealt_cards = random.sample(deck_of_cards, 6)
player1_hand, player2_hand = dealt_cards[:3], dealt_cards[3:]

要生成所有可能的组合,您可以使用大小为6的itertools.combinations();但是你仍然需要找到所有可能的排列,将这6张牌分为2手牌,这些牌是独一无二的:

for dealt_cards in itertools.combinations(deck_of_cards, 6):
    for hand1 in itertools.combinations(dealt_cards, 3):
        hand2 = tuple(card for card in dealt_cards if card not in hand1)

所以每张6张牌的组合,3张牌的所有组合都会给予一名玩家,其余3张牌则留给另一名玩家。

这产生了预期的解决方案数量:

>>> from itertools import combinations
>>> deck = range(9)
>>> sum(1 for dealt in combinations(deck, 6) for _ in combinations(dealt, 3))
1680

和演示:

>>> for dealt_cards in combinations(deck, 6):
...     for hand1 in combinations(dealt_cards, 3):
...         hand2 = tuple(card for card in dealt_cards if card not in hand1)
...         print hand1, hand2
... 
(0, 1, 2) (3, 4, 5)
(0, 1, 3) (2, 4, 5)
(0, 1, 4) (2, 3, 5)
(0, 1, 5) (2, 3, 4)
(0, 2, 3) (1, 4, 5)
# ...
(4, 6, 7) (3, 5, 8)
(4, 6, 8) (3, 5, 7)
(4, 7, 8) (3, 5, 6)
(5, 6, 7) (3, 4, 8)
(5, 6, 8) (3, 4, 7)
(5, 7, 8) (3, 4, 6)
(6, 7, 8) (3, 4, 5)

你也可以只用1手制作玩家,然后继续使用牌组的剩余部分来制作2手牌:

for hand1 in itertools.combinations(deck_of_cards, 3):
    for hand2 in itertools.combinations([c for c in deck_of_cards if c not in hand1], 3):
        # ...

具有相同的预期计数输出和结果:

>>> sum(1 for dealt in combinations(deck, 3) for _ in combinations([c for c in deck if c not in dealt], 3))
1680
>>> for hand1 in combinations(deck, 3):
...     for hand2 in combinations([c for c in deck if c not in hand1], 3):
...         print hand1, hand2
... 
(0, 1, 2) (3, 4, 5)
(0, 1, 2) (3, 4, 6)
(0, 1, 2) (3, 4, 7)
(0, 1, 2) (3, 4, 8)
(0, 1, 2) (3, 5, 6)
# ...
(6, 7, 8) (1, 3, 4)
(6, 7, 8) (1, 3, 5)
(6, 7, 8) (1, 4, 5)
(6, 7, 8) (2, 3, 4)
(6, 7, 8) (2, 3, 5)
(6, 7, 8) (2, 4, 5)
(6, 7, 8) (3, 4, 5)

虽然现在顺序不同。

答案 1 :(得分:1)

combinations = itertools.combinations(cards, 6)

这会给你6张选择的牌,然后你需要在2名玩家中分配这6张牌,所以:

possibilities = []
for combination in combinations:
    hands = []
    hand1 = itertools.combinations(combination, 3)
    hands.append(hand1)#Hand1
    hands.append([x for x in combination if x not in hand1])#Hand2
    possibilities.append(hands)

这将生成一个列表possibilities,其中每个项目都是2个不同牌局的列表。

答案 2 :(得分:-1)

只要获得6张牌的所有可能组合都不会削减它,因为单个玩家手中的订单并不重要,但重要的是谁拥有哪些牌。

因此,对于9张牌中的3张牌的所有组合,请从剩下的6张牌中选择3张其他牌:

from itertools import combinations

def getCardCombinations(cards):
    cards = set(cards)
    for first in combinations(cards, 3):
        for second in combinations(cards - set(first), 3):
            yield first, second

cards = [1,2,3,4,5,6,7,8,9]

all_combinations = getCardCombinations(cards)

答案 3 :(得分:-2)

如果我理解你的话,你希望得到每个可能的组合,从9中选择6个。因为命令并不重要(我们可以将前3个视为玩家1' s和第2个批量3作为玩家2的手,我们可以使用itertools.combinations

from itertools import combinations, izip
hands = combinations(cards, 6)

我理解你的问题了吗?

编辑:将这些分成两只手,每只手3只,你可以使用:

player1, player2 = izip(*map(lambda x: (x[:3], x[3:]), combinations(cards, 6)))