Different behaviour when operating on equivalent multidimensional lists
<p>When I operate on two, I think equivalent multidimensional lists, I have different outcomes. The only difference between the lists is how they are created. I'm using Python 3.4.3</p>

<pre><code>&gt;&gt;&gt; b = [[1,2],[1,2]]
&gt;&gt;&gt; b[0][0] += 1
&gt;&gt;&gt; b
[[2, 2], [1, 2]]
&gt;&gt;&gt; b = [[1,2]] * 2
&gt;&gt;&gt; b
[[1, 2], [1, 2]]
&gt;&gt;&gt; b[0][0] += 1
&gt;&gt;&gt; b
[[2, 2], [2, 2]]
</code></pre>

<p>As you can see, both b's and the operations on them are the same, but the outcome is not. I'm guessing that it has something to do with the way they are created since that is the only difference, but I don't see how.</p>

<p>Its the same with Python 2.7.6</p>

<pre><code>&gt;&gt;&gt; b = [[1,2],[1,2]]
&gt;&gt;&gt; b
[[1, 2], [1, 2]]
&gt;&gt;&gt; c = [[1,2]] * 2
&gt;&gt;&gt; c
[[1, 2], [1, 2]]
&gt;&gt;&gt; c == b
True
&gt;&gt;&gt; b[0][0] += 1
&gt;&gt;&gt; b
[[2, 2], [1, 2]]
&gt;&gt;&gt; c[0][0] += 1
&gt;&gt;&gt; c
[[2, 2], [2, 2]]
&gt;&gt;&gt; c == b
False
&gt;&gt;&gt; 
</code></pre>

<pre><code>b = [[1,2],[1,2]]

print(id(b[0])) # 139948012160968
print(id(b[1])) # 139948011731400

b = [[1,2]]*2

print(id(b[0])) # 139948012161032
print(id(b[1])) # 139948012161032
</code></pre>

<p><a href="https://docs.python.org/3/library/functions.html#id" rel="nofollow">`id() shows the object's ID or the memory location in Python.</a></p>

<p>When you do <code>b = [[1,2]]*2</code> you are basically saying let's point to the same object twice and store it in b in a list.</p>

<p>When you do <code>b = [[1,2],[1,2]]</code> you are basically saying let me get two different objects and put them in a list and let b reference the list.</p>

<p>So for the latter example, of course you are going to get that output since they are the same object you are changing. You can think of it as me giving you the same address to a house and I have the same address I gave you. We end up at the same place and what ever changes we make to the house, we see it together. </p>

<p>Edited for comment:</p>

<p>Correct! They are changing how the memory is handled but the values are the same.</p>

<p><code>==</code> tests if the values are the same. <code>is</code> tests if the objects are the same. so in our case:</p>

<pre><code>#First case:
print(b[0] == b[1]) #true
print(b[0] is b[1]) #false

#second case:
print(b[0] == b[1]) #true
print(b[0] is b[1]) #true
</code></pre>

<p>Edited second time for second comment!~</p>

<pre><code>import copy
x = [1,2]
b = [copy.copy(x) for i in range(3)]
print(id(b[0])) #140133864442248
print(id(b[1])) #140133864586120
print(id(b[2])) #140133864568008
print(b) #[[1, 2], [1, 2], [1, 2]] you can extend range to 256. 
</code></pre>

<p>If you want a unique object and want to copy it from another object, try using <a href="https://docs.python.org/3.5/library/copy.html" rel="nofollow">copy</a>. It makes a new object with the same values.</p>

<p>Edited again using one of my favorite function <code>sum</code>:</p>

<p>This is more or less redundant and it might confuse you some more, but <code>sum</code> also works too.</p>

<pre><code> x = [1,2]
 b = [sum([x],[]) for i in range(3)]
 print(id(b[0])) #140692560200008
 print(id(b[1])) #140692559012744
 print(b) #[[1, 2], [1, 2], [1, 2]]
</code></pre>

<p>Will return different instances in the object. I only point this is just in case you don't want to import copy or import anything.  </p>

python list