2
import itertools

ranks = '23456789TJQKA'

deck = [r+s for r in ranks for s in 'dchs']

allholdemhands = [i for i in itertools.combinations(deck,2)]


def allcombos(hand,group):
    'give all combos of a given hand for a given game'
    return [i for i in group if (i[0][0] == hand[0] and i[1][0] == hand[1])
            or (i[0][0] == hand[1] and i[1][0] == hand[0])]

def allbettercombos(cards,group):
    'all combos as good as or better, of that type'
    if cards[0] == cards[1]:
        betterpairs = [i+i for i in ranks if ranks.index(i) >= 
                        ranks.index(cards[0])]
        return [allcombos(x,group) for x in betterpairs]
    else:
        bettercards = [cards[0]+i for i in ranks 
                        if ranks.index(i) >= ranks.index(cards[1]) 
                        and ranks.index(i) < ranks.index(cards[0])]
        return [allcombos(x,group) for x in bettercards]

def makerange(hands, group = allholdemhands):
    'create a range of all hands from list of types'
    handrange = []
    for hand in hands:
        if hand[-1] != '+':
            handrange.append(allcombos(hand,group))
        else:
            handrange.append(allbettercombos(hand,group))
    return handrange

Above is code to allow the makerange function to take as input some set of holdem poker hands or ranges and output a list of every possible unique card combination there is.

It works but the output comes out as a list, length 1 and I would like it to be a list with a length equal to the number of combinations of cards it represents.

  • Can someone tell me how to change the code so the below output would be a list of length 38, with each hand as an element?

PS: a quick primer on the syntax of the input for makerange:

makerange(['AA','KJ+']) would output:

[[('Ad', 'Ac'), ('Ad', 'Ah'), ('Ad', 'As'), ('Ac', 'Ah'), ('Ac', 'As'), ('Ah', 'As')], [[('Td', 'Kd'), ('Td', 'Kc'), ('Td', 'Kh'), ('Td', 'Ks'), ('Tc', 'Kd'), ('Tc', 'Kc'), ('Tc', 'Kh'), ('Tc', 'Ks'), ('Th', 'Kd'), ('Th', 'Kc'), ('Th', 'Kh'), ('Th', 'Ks'), ('Ts', 'Kd'), ('Ts', 'Kc'), ('Ts', 'Kh'), ('Ts', 'Ks')], [('Jd', 'Kd'), ('Jd', 'Kc'), ('Jd', 'Kh'), ('Jd', 'Ks'), ('Jc', 'Kd'), ('Jc', 'Kc'), ('Jc', 'Kh'), ('Jc', 'Ks'), ('Jh', 'Kd'), ('Jh', 'Kc'), ('Jh', 'Kh'), ('Jh', 'Ks'), ('Js', 'Kd'), ('Js', 'Kc'), ('Js', 'Kh'), ('Js', 'Ks')], [('Qd', 'Kd'), ('Qd', 'Kc'), ('Qd', 'Kh'), ('Qd', 'Ks'), ('Qc', 'Kd'), ('Qc', 'Kc'), ('Qc', 'Kh'), ('Qc', 'Ks'), ('Qh', 'Kd'), ('Qh', 'Kc'), ('Qh', 'Kh'), ('Qh', 'Ks'), ('Qs', 'Kd'), ('Qs', 'Kc'), ('Qs', 'Kh'), ('Qs', 'Ks')]]]

This represents all 6 ways to make AA and all 32 hands that have a high card K and at least a J as the second highest.

1 Answers1

0

I don't know if it is the best way to do it, but it answers your question.

Rewrite your functions into generators, like this:

def allcombos(hand,group):
    'give all combos of a given hand for a given game'
    for i in group:
        if (i[0][0] == hand[0] and i[1][0] == hand[1]) or (i[0][0] == hand[1] and i[1][0] == hand[0]):
            yield i

def allbettercombos(cards,group):
    'all combos as good as or better, of that type'
    if cards[0] == cards[1]:
        betterpairs = [i+i for i in ranks if ranks.index(i) >= ranks.index(cards[0])]
        for x in betterpairs:
            for hand in allcombos(x,group):
                yield hand
    else:
        bettercards = [cards[0]+i for i in ranks if ranks.index(i) >= ranks.index(cards[1]) and ranks.index(i) < ranks.index(cards[0])]
        for x in bettercards:
            for hand in allcombos(x,group):
                yield hand

and adapt makerange like so:

def makerange(hands, group = allholdemhands):
    'create a range of all hands from list of types'
    handrange = []
    for hand in hands:
        if hand[-1] != '+':
            for hand in allcombos(hand,group):
                handrange.append(hand)
        else:
            for hand in allbettercombos(hand,group):
                handrange.append(hand)
    return handrange

Now, when you call print makerange(['AA','KJ+']) the output is a list with a length of 38:

[('Ad', 'Ac'), ('Ad', 'Ah'), ('Ad', 'As'), ('Ac', 'Ah'), ('Ac', 'As'), ('Ah', 'As'), ('Jd', 'Kd'), ('Jd', 'Kc'), ('Jd', 'Kh'), ('Jd', 'Ks'), ('Jc', 'Kd'), ('Jc', 'Kc'), ('Jc', 'Kh'), ('Jc', 'Ks'), ('Jh', 'Kd'), ('Jh', 'Kc'), ('Jh', 'Kh'), ('Jh', 'Ks'), ('Js', 'Kd'), ('Js', 'Kc'), ('Js', 'Kh'), ('Js', 'Ks'), ('Qd', 'Kd'), ('Qd', 'Kc'), ('Qd', 'Kh'), ('Qd', 'Ks'), ('Qc', 'Kd'), ('Qc', 'Kc'), ('Qc', 'Kh'), ('Qc', 'Ks'), ('Qh', 'Kd'), ('Qh', 'Kc'), ('Qh', 'Kh'), ('Qh', 'Ks'), ('Qs', 'Kd'), ('Qs', 'Kc'), ('Qs', 'Kh'), ('Qs', 'Ks')]

More info here. Now maybe the code could be refactored, but it should work like you want.

Mrioddo
  • 25
  • 7
  • @mariomendoza You're welcome! If it solved your problem, please accept it as an answer! From the [Help Center](https://stackoverflow.com/help/someone-answers): "Please do not add a comment on your question or on an answer to say 'Thank you'. [...] If you want to say 'thank you,' vote on or accept that person's answer [...]." – Mrioddo Nov 05 '17 at 05:16