Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split list recursively until flat

Tags:

python

I'm writing a passion program that will determine the best poker hand given hole cards and community cards. As an ace can go both ways in a straight, I've coded this as [1, 14] for a given 5 card combination.

I understand recursion but implementing it is a different story for me. I'm looking for a function that will split all aces recursively, into all possible hand combinations until all nested lists are exhausted. This should obviously work with up to 4 aces, overlooking the fact that you wouldn't care about a straight at that point in all likelihood.

hand = [[1, 14], 2, 3, [1, 14], 7]

desired_output = [
        [1, 2, 3, 1, 7],
        [1, 2, 3, 14, 7],
        [14, 2, 3, 1, 7],
        [14, 2, 3, 14, 7]
        ]

I'm not proud of what I have so far, especially because it returns a list instead of something like a yield which would build the list I'm looking for:

def split_first_ace(hand):
    aces = [True if isinstance(x, list) else False for x in hand]
    for i, x in enumerate(aces):
        if x:
            ranks_temp = hand.copy()
            ace = ranks_temp.pop(i)
            return [[ace[0]] + ranks_temp, [ace[1]] + ranks_temp]

Any help on a solution would be appreciated, mostly because it'll help me understand how to implement recursion. But I'm open to other solutions as well.

like image 766
Balter Avatar asked Aug 29 '20 02:08

Balter


People also ask

How do you split a list into evenly sized chunks?

The easiest way to split list into equal sized chunks is to use a slice operator successively and shifting initial and final position by a fixed number.

How do you flatten a nested list using recursion in Python?

Step-by-step Approach:In that recursive function, if we find the list as empty then we return the list. Else, we call the function in recursive form along with its sublists as parameters until the list gets flattened. Then finally, we will print the flattened list as output.


2 Answers

Well, there is an easier way to do this:

from itertools import product

product(*[i if isinstance(i, list) else [i] for i in hand])

I challenge everybody to come up with a simpler solution

like image 65
Marat Avatar answered Nov 03 '22 20:11

Marat


The itertools.product() function might be useful. If we assume that the recursion will only be 1 level deep (aces don't have nested lists themselves), then we could use the following:

from itertools import product

hand = [[1, 14], 2, 3, [1, 14], 7]

aces = [x for x in hand if isinstance(x, list)]
rest = [x for x in hand if isinstance(x, int)]

combinations = [list(x) + rest for x in product(*aces)]
print(combinations)

Yields:

[[1, 1, 2, 3, 7], [1, 14, 2, 3, 7], [14, 1, 2, 3, 7], [14, 14, 2, 3, 7]]
like image 10
Aaron Keesing Avatar answered Nov 03 '22 21:11

Aaron Keesing