Fill a multidimensional array efficiently that have many if else statements
<p>I want to fill an 4dim numpy array in a specific and efficient way. Because I don't know better I startet to write the code with if else statements, but that doesn't look nice, is probably slow and I also can not be really sure if I thought about every combination. Here is the code which I stopped writing down:</p>

<pre><code>sercnew2 = numpy.zeros((gn, gn, gn, gn))
for x1 in range(gn):
    for x2 in range(gn):
        for x3 in range(gn):
            for x4 in range(gn):
                if x1 == x2 == x3 == x4: 
                    sercnew2[x1, x2, x3, x4] = ewp[x1]
                elif x1 == x2 == x3 != x4:
                    sercnew2[x1, x2, x3, x4] = ewp[x1] * ewp[x4]
                elif x1 == x2 == x4 != x3:
                    sercnew2[x1, x2, x3, x4] = ewp[x1] * ewp[x3]
                elif x1 == x3 == x4 != x2:
                    sercnew2[x1, x2, x3, x4] = ewp[x1] * ewp[x2]
                elif x2 == x3 == x4 != x1:
                    sercnew2[x1, x2, x3, x4] = ewp[x2] * ewp[x1]
                elif x1 == x2 != x3 == x4:
                    sercnew2[x1, x2, x3, x4] = ewp[x1] * ewp[x3]
                elif ... many more combinations which have to be considered
</code></pre>

<p>So basically what should happen is, that if all variables (x1, x2, x3, x4) are different from each other, the entry would be: </p>

<pre><code>sercnew2[x1, x2, x3, x4] = ewp[x1]* ewp[x2] * ewp[x3] * ewp[x4]
</code></pre>

<p>Now if lets say the variable x2 and x4 is the same then:</p>

<pre><code>sercnew2[x1, x2, x3, x4] = ewp[x1]* ewp[x2] * ewp[x3]
</code></pre>

<p>Others examples can be seen in the code above. Basically if two or more variables are the same, then I only consider on of them. I hope the pattern is clear. Otherwise please let me note and I will try to express my problem better. I am pretty sure, that there is a much more intelligent way to do it. Hope you know better and thanks in advance :)   </p>

<p>I don't really know what you mean by saying that those variables are the same, but if indeed they are, than all you have to do is just use <code>set()</code>.</p>

<pre><code>from functools import reduce
from operator import mul
sercnew2 = numpy.zeros((gn, gn, gn, gn))
for x1 in range(gn):
    for x2 in range(x1, gn):
        for x3 in range(x2, gn):
            for x4 in range(x3, gn):
                set_ = [ewp[n] for n in set([x1, x2, x3, x4])]
                sercnew2[x1, x2, x3, x4] = reduce(mul, set_, 1)
</code></pre>

<p>The way it works is that it creates a <code>set()</code> which delete duplicates, and later with <code>reduce</code> function I pick first number from the <code>set_</code>, multiplies it with <code>1</code> (the initializer value), and the result of this is going to be passed to <code>reduce</code> as first argument, and second will be the second item from <code>set_</code>. Sorry for my bad explanation.</p>

python arrays numpy