Poker hand evaluator using NumPy I'm trying to write a Poker hand evaluator using NumPy, because I find pure Python is pretty slow.

def eval_(*args):

    if len(args) == 5: 
        hand = np.asarray([*args], dtype=np.int8)
    else:
        hand = np.asarray(args[0], dtype=np.int8)

    ranks = np.bincount(hand // 4, minlength = 13)  
    count = np.array([np.where(ranks == count)[0] for count in range(5)])

    if len(count[4]):
        return 8, count[4][0], count[1][0]
    if len(count[3]) and len(count[2]):
        return 7, count[3][0], count[2][0]
    if len(count[3]):
        return 4, count[3][0], count[1][1], count[1][0]
    if len(count[2]) == 2:
        return 3, count[2][1], count[2][0], count[1][0]
    if len(count[2]):
        return 2, count[2][0], count[1][2], count[1][1], count[1][0]

    is_straight = count[1][0] + 4 == count[1][4]
    is_acestraight = count[1][4] - 9 == count[1][3]
    is_flush = 5 in np.bincount(hand % 4)
    if is_straight: return 5 + 4 * is_flush, count[1][4]
    if is_acestraight: return 5 + 4 * is_flush, 3

    return 1 + 5 * is_flush, count[1][4], count[1][3], count[1][2], count[1][1], count[1][0]


I'm not satisfied with my code. I don't like all kinds of count[1][2] calls, I should be able to just attach the whole count[1] array to my return value but I don't know how to do it. And I have trouble with np.where(). I don't think I should use list comprehension for different count values on this:

count = np.array([np.where(ranks == count)[0] for count in range(5)])


but I have no idea.
I find [interpreted] pure python is pretty slow.


Yes, that's true. And numpy operations can offer speed advantages, since its loops are coded in compiled C. But that's only significant when manipulating large arrays, and 5 seems like a pretty small number, too small to realize gains. (I think eval_() only evaluates a single hand at a time, it's not like you're passing in thousands of hands in a single call.)

Yes, you could return count[1] instead of count[1][2], but that's quite a different thing, presenting callers with a different API. Would you please state your concern in terms of what values the caller should receive, similar to a unit test?

The list comprehension you use seems pretty reasonable to me.

You have lots and lots of magic numbers that you might define identifiers for.

It wouldn't hurt to mention https://en.wikipedia.org/wiki/List_of_poker_hands in a comment, if that matches the rankings you're returning.