title: Adding conditions to python function `set_partitions`
body: <p>I want to work with a given group of elements and reorder them as the function <code>set_partitions</code> do but adding a condition to this lists, I will try to explain my problem in a understandable and simple way. A example of how this function works,</p>
  <pre><code>from more_itertools import set_partitions
  
  a=[1,2,3]
  
  print(list(set_partitions(a)))
  </code></pre>
  <p>And return the possible agrupations,</p>
  <pre><code>[[[1,   2,   3]], 
   [[1], [2,   3]],
   [[1,   2], [3]],
   [[2], [1,   3]],
   [[1], [2], [3]]]
  </code></pre>
  <p>I want to put a constrain in this function (for example could be, the groups created need to sum a even number). I can simply extract the arrays and apply the constrains, but my problem is that I need to do it for a huge number of list elements, and my computer dies before finishing. If I apply the constrain directly to the function <code>set_partitions</code> the problem will be reduced because the constrain applied is very strong, i mean, for example it reduce a total amount of 4213597 million possible combinations to 12k valid combinations (but i can not go further because of memory problems), so applying the condition will solve the problem.</p>
  <p>For this I need to understand the function <code>set_partitions</code>, this function can be used only copying the following code without needing other auxiliar functions, or to import anything,</p>
  <pre><code>def set_partitions(iterable, k=None):
  
      L = list(iterable)
      n = len(L)
  
      def set_partitions_helper(L, k):
          n = len(L)
          if k == 1:
              yield [L]
          elif n == k:
              yield [[s] for s in L]
              
          else:
              
              e, *M = L
              
              for p in set_partitions_helper(M, k - 1):
                  yield [[e], *p]
                  
              for p in set_partitions_helper(M, k):
                  
                  for i in range(len(p)):
                      yield p[:i] + [[e] + p[i]] + p[i + 1 :]
  
      for k in range(1, n + 1):
          yield from set_partitions_helper(L, k)
  </code></pre>
  <p>I' have experience programming and is my work but I do not arrive to this level, so there is some things in the function that I do not understand, as for example what is doing,
  <code>e, *M = L</code> or the following elements in the helper function.</p>
  <p>I need some help understanding how work this function for finding <strong>where the condition can be placed</strong>.</p>
  <p>Thanks a lot!</p>
  <p>Addition explaining my specific case:</p>
  <p>The elements I'm trying to group  in partitions are matrixes in tensorial product, for example chains of fixed lenght for example,</p>
  <p><a href="https://i.stack.imgur.com/YgAPA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YgAPA.png" alt="enter image description here" /></a></p>
  <p>A element will be a chain of this style, that we can represent as a string,</p>
  <p><code>'xz11y'</code></p>
  <p>I want the elements of the subgroups to commute, <code>1</code> commute with everything, <code>x/y/z</code> only commutes with itself (and the identity), so we need to compare the chains only, so for example if we have the 3 matrixes,</p>
  <p><code>['1z'],['zz'],['x1']</code></p>
  <p>A valid agrupation will be</p>
  <p><code>'1z','zz' | 'x1'</code></p>
  <p>Because <code>'1z'</code> commutes with <code>zz</code>.</p>
  <p>A invalid agrupation will be</p>
  <p><code>'1z' | 'zz', 'x1'</code></p>
  <p>Because <code>'zz'</code> and <code>'x1'</code> have a x and a z in same position, and this operators do not commute.</p>
  <p>This is simplified, so I have a Hamiltonian of about 19 or more separate operators of this type and I need to find the agrupations that conserve this commutation.</p>