-3

I have a tuple (1,2,5,3,2,1,3,4,1) and want to find the amount of combinations of 1 and 2. So in this example it should return 2 because there are 3 times a 1 but only 2 times a 2.

The task that I want to solve is:

Give the amount of possible combinations by 1 and 2. Each number can only be used once for a combination.

I already solved the issue with this code:

    count1 = tuple.count(number1)
    count2 = tuple.count(number2)
    if count1 < count2:
        return count1
    else:
        return count2
    return count1

But because I want to learn more magic things with numpy, I would like to know if there is a better solution to use it here.

Asara
  • 2,791
  • 3
  • 26
  • 55
  • 1
    In what way is this the "amount of combinations"? Looks more like the minimum count to me. – wim Nov 27 '17 at 23:34
  • 1
    What do you mean by "the amount of combinations of 1 and 2"? It's not clear whether your existing code is correct. – user2357112 Nov 27 '17 at 23:34
  • [Do not repost a question just because the other one was closed.](https://stackoverflow.com/questions/47518293/count-occurences-of-all-items-of-a-list-in-a-tuple) – jhpratt Nov 27 '17 at 23:35
  • its another task than in the other question, here the combinations should be found, not the all occurences – Asara Nov 27 '17 at 23:45
  • I edited the question to make it more clearly, please stop downvoting just because you don't understand the task. Better ask so I can improve the text... – Asara Nov 27 '17 at 23:48

1 Answers1

1

Your if/else can be expressed more compactly with min:

In [707]: tup = (1,2,5,3,2,1,3,4,1)
In [708]: max(tup.count(1), tup.count(2))
Out[708]: 3
In [709]: min(tup.count(1),tup.count(2))
Out[709]: 2

numpy won't improve on this. There is a bincount, that counts all values in a range.

In [710]: arr = np.array(tup)
In [711]: arr
Out[711]: array([1, 2, 5, 3, 2, 1, 3, 4, 1])
In [712]: np.bincount(arr)
Out[712]: array([0, 3, 2, 2, 1, 1], dtype=int32)

We could select a could select a couple of values and as before get their min:

In [716]: np.bincount(arr)[[1,2]]
Out[716]: array([3, 2], dtype=int32)
In [717]: min(np.bincount(arr)[[1,2]])
Out[717]: 2

Keep in mind that np.array(tup) takes time; so sticking with list operations is often faster.

Another array approach is to use a broadcasted == test

In [532]: arr == [[1],[2]]
Out[532]: 
array([[ True, False, False, False, False,  True, False, False,  True],
       [False,  True, False, False,  True, False, False, False, False]], dtype=bool)
In [533]: _.sum(axis=1)
Out[533]: array([3, 2])

using sum on the booleans to count them.

There's also Counter class that can count all values in one call:

In [534]: from collections import Counter
In [535]: Counter(tup)
Out[535]: Counter({1: 3, 2: 2, 3: 2, 4: 1, 5: 1})
In [536]: min(_[1],_[2])
Out[536]: 2
hpaulj
  • 221,503
  • 14
  • 230
  • 353