Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Nested Loops on Lists

I have the following code to compute all the possible combinations of odds for a number of games. I would like to do the following

  1. Remove all the ugly nested loops.
  2. Allow dynamic games, i.e I will not have to stay creating a match list adding and add an entry to the nested loop. (ex I want to add match k)

Code is as follows;

import numpy as np

"""
Odds Predictions.
----------------------------------------
"""

bet_amount = 1.00

# Set up odds of all teams in groups, touple contains odds for coming in first place and second place.
match_a = [("RUS-W", 2.37), ("RUS-X", 3.20), ("RUS-L", 3.50)]
match_b = [("ROM-W", 3.30), ("ROM-X", 3.10), ("ROM-L", 2.50)]
match_c = [("FRA-W", 1.25), ("FRA-X", 6.00), ("FRA-L", 11.00)]
match_d = [("ENG-W", 1.57), ("ENG-X", 4.00), ("END-L", 7.00)]
match_e=  [("UKR-W", 1.57), ("UKR-X", 4.00), ("UKR-L", 7.00)]
match_f = [("GER-W", 1.57), ("GER-X", 4.33), ("GER-L", 6.50)]
match_g = [("ITA-W", 1.83), ("ITA-X", 3.50), ("ITA-L", 5.25)]
match_h = [("CZK-W", 4.75), ("CZK-X", 3.50), ("CZK-L", 1.90)]
match_i = [("SPA-W", 1.40), ("SPA-X", 4.75), ("SPA-L", 10.00)]
match_j = [("BEL-W", 1.72), ("BEL-X", 3.80), ("BEL-L", 5.50)]

totals = []
total_rank = []
count = 0

print 'Computing Combinations'

for mat_a in match_a:
  for mat_b in match_b:
    for mat_c in match_c:
      for mat_d in match_d:
        for mat_e in match_e:
          for mat_f in match_f:
            for mat_g in match_g:
              for mat_h in match_h:
                for mat_i in match_i:
                  for mat_j in match_j:

                    entry = '%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,' % (mat_a[0] , mat_b[0] , mat_c[0] , mat_d[0] , mat_e[0] , mat_f[0], mat_g[0] , mat_h[0] , mat_i[0] , mat_j[0])
                    rank = mat_a[1] * mat_b[1] * mat_c[1] * mat_d[1] * mat_e[1] * mat_f[1]* mat_g[1] * mat_h[1] * mat_i[1] * mat_j[1]

                    totals.append([entry, rank])
                    total_rank.append(totals)

                    count += 1

print 'Total Combinations : %d ' % count
print 'Sorting Combinations'

totals = sorted(totals,key=lambda x: x[1])

print 'Bet Amount : %f' % bet_amount

for count, total in enumerate(totals):
  if count < 100:
    print ' %s  ->  %s' % (total[0], total[1] * bet_amount)
  else:
    break;
like image 853
Ian Daz Avatar asked Jan 24 '26 18:01

Ian Daz


1 Answers

You should have a look at itertools.product. Also, your total_rank list seems to be kind of pointless (note that it will contain many refrences to the same list over and over again) and count is just the len of the resulting list.

import itertools, operator
matches = [match_a, match_b, match_c, match_d, match_e, match_f, match_g, match_h, match_i, match_j]

for mat_x in itertools.product(*matches):
    entry = ", ".join(x[0] for x in mat_x)
    rank = reduce(operator.mul, (x[1] for x in mat_x))
    totals.append([entry, rank])

print 'Total Combinations : %d ' % len(totals)

You could even make this a list comprehension:

totals = [(", ".join(x[0] for x in mat_x), reduce(operator.mul, (x[1] for x in mat_x))) 
          for mat_x in itertools.product(*matches)]
like image 133
tobias_k Avatar answered Jan 26 '26 08:01

tobias_k



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!