Home > Back-end >  How to arrange combinations by odds and evens in Python 3?
How to arrange combinations by odds and evens in Python 3?

Time:12-16

I have the following code to make a list of combinations of 5 integers from 1 up to 20:

from itertools import combinations
combos = []
for x in combinations(range(1,21,5)):
    combos.append(x)

How can I extract only the combinations that have, say 4 odd numbers (and 1 even number) and put them in a separate list?

I tried writing some code to make lists of the odd and even values:

odds = []
evens = []
for y in range(21):
   if y%2 == 0:
     evens.append(y)
  else:
     odds.append(y)

and set up another loop like so:

odd4_even1: []
for z in combos:
    # if number of odds in combos == 4:
        # odd4_even1.append(z)

How can I implement the commented-out part?

CodePudding user response:

You could just add up the number of odd numbers that are in x in the combination for loop and sort them into groups based on the odd number count without ever having to make an even or odd list, or having to iterate the full list over again at all.

You can use a dictionary where the keys are the number of odd integers in the sequences, and the values will be a list containing all of the sequences containing that many odd integers.

from itertools import combinations

groups = {}
for x in combinations (range(1,21),5):
    odd_count = sum([1 for i in x if i%2 == 1])
    groups.setdefault(odd_count, [])
    groups[odd_count].append(x)

print({i:len(groups[i]) for i in groups})

OUTPUT:

{3: 5400, 2: 5400, 4: 2100, 1: 2100, 5: 252, 0: 252}

So if you wanted the list that contains 4 odd numbers and 1 even you would just use groups[4] or if you wanted the group that contains 1 odd and 4 evens use groups[1]


If for some reason you really wanted to do it the way you are currently using you could do something like this:

odd4_even1 = []
for z in combos:
    total = 0
    for num in z:
        if num in odds:
            total  = 1
    if total == 4:
        odd4_even1.append(z)

print(len(odd4_even1)) # 2100
  • Related