[SOLVED] Strange comportement of list/array

Issue

I want to understand why the comportement of my array is like that:

import numpy as np
import math
n=10
P=np.array([[0]*n]*n)
P[2][2]=1 #It works as I want
for i in range(n):
    for j in range(n):
        P[i][j]=math.comb(n,j+1)*((i+1)/n)**(j+1)*(1-(i+1)/n)**(n-j-1)
        print(math.comb(n,j+1)*((i+1)/n)**(j+1)*(1-(i+1)/n)**(n-j-1))
print(P)

I get as a result for P an array with only 0 except 1 for the (n,n) position but values printed are not 0.

I suppose it comes from the fact that I use [[0]*n]*n for my list with mutable/immutable variable because it works well when I use np.zeros() but I don’t understand why it works when I set value manually (with P[2][2]=1 for example)

Thanks

Solution

The way you are creating the array is defaulting to an integer dtype because it uses the first value to determine the type if you don’t explicitly set it. You can demonstrate this by trying to assign a float instead of an int with

P[2][2]=1   #It works as I want
P[2][2]=0.3 #It doesn't work

To use your approach you need to create an array with a dtype of float so values don’t get clipped: P=np.array([[0.0]*n]*n) or P=np.array([[0]*n]*n, dtype=float).

This will produce an array of the expected values:

array([[3.87420489e-01, 1.93710245e-01, 5.73956280e-02, 1.11602610e-02,
        1.48803480e-03, 1.37781000e-04, 8.74800000e-06, 3.64500000e-07,
        9.00000000e-09, 1.00000000e-10],
       [2.68435456e-01, 3.01989888e-01, 2.01326592e-01, 8.80803840e-02,
        2.64241152e-02, 5.50502400e-03, 7.86432000e-04, 7.37280000e-05,
        4.09600000e-06, 1.02400000e-07], 
       ...

Answered By – Mark

Answer Checked By – David Goodson (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *