5

I want to set value of G[1][0],G[1][1]...G[1][100] and G[0][1],G[1][1]...G[100][1] to be 1

G = [[0]*101]*101
G[1][:] = 1
G[:][1] = 1

Than I got error,

...
G[1][:] = 1
TypeError: can only assign an iterable

how can I do this without Numpy?

Spike
  • 319
  • 3
  • 17

4 Answers4

6

There are a few flaws here.

First: Iterator assignment

First of all, the left-hand side of your assignment yields an iterable, so you can't assign a scalar to that. Instead, the right-hand side (in your case 1) needs to be an iterable of equal length, e.g.:

G[0][:] = [0] * 101 # Warning: Copied code from question, still flawed

Second: List of list references

You initialize your list in-line. This is okay for a list of literals, but will fail for the second dimension, as it will hold 101 references to the same internal list. Changing one element in there will have effects on all other indices.

You want to initialize your list like this:

G = [[0] * 101 for x in range(102)]

Third: List slice / hard-copy

The next thing is, that the [:]-call creates a hard-copy of your list. So what happens here, is:

  • G[0][:] takes the first column of your 2d list and hard-copies it.
  • G[:][0] hard-copies the entire 2d list and then returns the first column of that.

You probably do not want to copy the entire list around all the time, losing its reference and making changes only to the copies.

Finally: What you want

Assuming your first dimension refers to columns and your second dimension refers to rows:

Set all elements of a column to 1:

G[0] = [1] * 101

Set all elements of a row to 1:

for i in range(102): G[i][0] = 1
jbndlr
  • 4,965
  • 2
  • 21
  • 31
  • Amazing answer! What confused me most is the reason you explained in the second part. Thanks again! – Spike Mar 11 '16 at 12:00
2

First of all the way you created the list is wrong

See this question and answer

Using loop:

import pprint
lst = [[0]*10 for n in range(10)]
for i in range(len(lst[0][:])): #Iterating over column of first row
    lst[0][i] = 1
for j in range(len(lst)): #Iterating over row of first column 
    lst[j][0] =1
pprint.pprint(lst)

Output:

[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Community
  • 1
  • 1
The6thSense
  • 8,103
  • 8
  • 31
  • 65
1

The TypeError you get is because you are trying to assign an int to a list.

The simplest solution I can think is a for loop over the length of the vector you want to set to 1:

for i in range(len(G[1][:])):
    G[1][i] = 1

edit: I tested this code. It won't work for your set up as you instantiated G as a deep copy list of lists.

The proper way to instantiate your matrix would be:

 G = [[0 for x in range(101)] for x in range(101)]
Alvin
  • 383
  • 5
  • 16
1

First of all you need to understand what [[0]*101]*101 really does. The type of G is list of list, but each entry in the outer list G is a reference to the same list. See Python list of lists, changes reflected across sublists unexpectedly. Most of the time this is not what you want.

Second, G[1][:] is a slice and requires an iterable object on the right hand side. There are multiple ways to achieve setting all values in a row, because you can also set the entry to a new list. Since you need to change the values also in different rows, I recommend using for loops to begin with.

Community
  • 1
  • 1
Markus
  • 592
  • 3
  • 13
  • Greet! I think I understand why `G[1][:]` and `G[:][1]` do not include elements `G[2][2]` or `G[3][4]` but I got an all `1` array. Is it because "each entry in the outer list G is a reference to the same list." as you said? – Spike Mar 11 '16 at 11:55