0

I have a list of lists of numpy arrays. I would like to loop through the list of lists and change certain elements. Below is an example, but just with integers:

    a = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]

    print(a)

    for i in range(len(a)):
         for j in range(i+1):
                if i == j:
                    a[i][j] = 100

    print(a)
This is the output:[[1, 1, 1], [1, 1, 1], [1, 1, 1]][[100, 1, 1], [1, 100, 1], [1, 1, 100]]

The i==j element has been changed to something else. When I run the exact same code logic, but with 2x2 numpy arrays, I cannot get it to do the same thing:

    L=3
    I = np.eye(2, dtype = int)
    sigplus = np.array([[0,2],[0,0]])
    plusoperatorlist=[[I]*L]*L

    print(plusoperatorlist)
    for i in range(len(plusoperatorlist)):
        for j in range(i+1):
                if i == j:
                    plusoperatorlist[i][j] = sigplus
    
    print(plusoperatorlist)
This is the output:[[array([[1, 0],[0, 1]]), array([[1, 0],[0, 1]]), array([[1, 0],[0, 1]])], [array([[1, 0],[0, 1]]), array([[1, 0],[0, 1]]), array([[1, 0],[0, 1]])], [array([[1, 0],[0, 1]]), array([[1, 0],[0, 1]]), array([[1, 0],[0, 1]])]][[array([[0, 2],[0, 0]]), array([[0, 2],[0, 0]]), array([[0, 2],[0, 0]])], [array([[0, 2],[0, 0]]), array([[0, 2],[0, 0]]), array([[0, 2],[0, 0]])], [array([[0, 2],[0, 0]]), array([[0, 2],[0, 0]]), array([[0, 2],[0, 0]])]]

It changes every element to the matrix sigplus that I defined. The desired output is to still have the list of lists of identity matrices, but have the sigplus matrix at the i==j position in the list of lists. Help is much appreciated :)

I have outlined what I tried above.

  • 1
    The problem isn't `numpy`, it's the construction of `plusoperatorlist=[[I]*L]*L`. `*L` is widely known to give unexpected results when creating nested lists. – hpaulj Mar 31 '22 at 16:03
  • Does this answer your question? [Why does using multiplication operator on list create list of pointers?](https://stackoverflow.com/questions/8822728/why-does-using-multiplication-operator-on-list-create-list-of-pointers) – Python learner Mar 31 '22 at 16:20
  • I created this list a different way: `plusoperators=[] plusoperators.extend(repeat(I,L)) plusoperatorlist=[] plusoperatorlist.extend(repeat(plusoperators,L)) ` and I still got the same erroneous output. Can you suggest something else to try? – Andrew Moyer Mar 31 '22 at 16:25

1 Answers1

1

The issue is that you created a nested list by multiplication of the original list. The reference to the original list will remain the same under the hood, which means seemingly changing one of the lists will actually change all of them. Try generating your nested list like:

plusoperatorlist= [[I for _ in range(L)] for _ in range(L)]

Now, every nested list has its own reference and can be changed independently.

Stefan
  • 897
  • 4
  • 13
  • @AndrewMoyer, good to hear. If this was what you were looking for then please accept the answer with the tick mark. – Stefan Mar 31 '22 at 18:38