title: How to calculate all possibilities of very large string matrixes timely?
body: <p>OK so let's say I have a situation where I have a bunch of objects in different classifications and I need to know the total possible combinations of these objects so I end up with an input that looks like this</p>
  
  <pre><code>{'raw':[{'AH':['P','C','R','Q','L']},
  {'BG':['M','A','S','B','F']},
  {'KH':['E','V','G','N','Y']},
  {'KH':['E','V','G','N','Y']},
  {'NM':['1','2','3','4','5']}]}
  </code></pre>
  
  <p>Where the keys AH, BG, KH, NM constitute groups, the values are list that hold individual objects and a finished group would constitute one member of each list, in this example KH is listed twice so each finished group would have 2 members of KH in it.  I build something that handles this, it looks like this.</p>
  
  <pre><code>class Builder():
  
      def __init__(self, data):
          self.raw = data['raw']
          node = []
          for item in self.raw:
              for k in item.keys():
                  node.append({k:0})
          logger.debug('node: %s' % node)
  
          #Parse out groups#
          self.groups = []
          increment = -2
          while True:
              try:
                  assert self.raw[increment].values()[0][node[increment][node[increment].keys()[0]]]
                  increment = -2
                  for x in self.raw[-1].values()[0]:
                      group = []
                      for k in range(0,len(node[:-1])):
                          position = node[k].keys()[0]
                          player = self.raw[k].values()[0][node[k][node[k].keys()[0]]]
                          group.append({position:player})
                      group.append({self.raw[-1].keys()[0]:x})
                      if self.repeatRemovals(group):
                          self.groups.append(group)
                  node[increment][node[increment].keys()[0]]+=1
              except IndexError:
                  node[increment][node[increment].keys()[0]] = 0
                  increment-=1
                  try:
                      node[increment][node[increment].keys()[0]]+=1
                  except IndexError:
                      break
          for group in self.groups:
              logger.debug(group)
  
      def repeatRemovals(self, group):
          for x in range(0, len(group)):
              for y in range(0, len(group)):
                  if group[x].values()[0] == group[y].values()[0] and x != y:
                      return False
  
          return True
  
  if __name__ == '__main__':
      groups = Builder({'raw':[{'AH':['P','C','R','Q','L']},
                                             {'BG':['M','A','S','B','F']},
                                             {'KH':['E','V','G','N','Y']},
                                             {'KH':['E','V','G','N','Y']},
                                             {'NM':['1','2','3','4','5']}]})
      logger.debug("Total groups: %d" % len(groups.groups))
  </code></pre>
  
  <p>The output of running this should clearly state my intended goal, if I have failed to do so in text. My concern is the time it takes to handle large classification of objects, when a classification has some 40 something objects in it, it is in the matrix three times and there are 7 other classifications with comparable object sizes. I think the numpy library could help me, but I am new to scientific programming and am not sure how to go about it, or if it would be worth it, could anyone provide some insight? Thank you.</p>