avatarCoucou Camille

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

1619

Abstract

references to the same item: a <b>shallow copy</b>. The list multiplication actually works in the first dimension but not the second:</p><div id="7b94"><pre>lst = <span class="hljs-comment">[1]</span> * 3 lst<span class="hljs-comment">[0]</span> = 0 lst >>> <span class="hljs-comment">[0, 1, 1]</span></pre></div><h2 id="a3eb">Other Possible Implementations</h2><ul><li>Nested for-loops</li></ul><div id="5319"><pre><span class="hljs-attribute">arr</span> <span class="hljs-operator">=</span> [[<span class="hljs-number">1</span> for i in range(<span class="hljs-number">3</span>)] for j in range(<span class="hljs-number">3</span>)]</pre></div><ul><li>For loop with list multiplication in inner lists</li></ul><div id="405a"><pre><span class="hljs-attribute">arr</span> <span class="hljs-operator">=</span> [[<span class="hljs-number">1</span>] * <span class="hljs-number">3</span> for i in range(<span class="hljs-number">3</span>)]</pre></div><ul><li>List multiplication but with deep copy for inner lists, here <code>lst[:]</code> is used to obtain a deepcopy of the original array hence the return array won’t be affected by any changes in the original objects.</li></ul><div id="a81e"><pre>arr = <span class="hljs-comment">[x<span class="hljs-comment">[:]</span> for x in <span class="hljs-comment">[<span class="hljs-comment">[1]</span> * 3]</span> * 3]</span></pre></div><p id="4746">The 3rd method list multiplication turns out to be the fasted among all three, method 2 quite similar and method 1 being the slowest:</p><figure id="f19b"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/

Options

1*hYGO3IlJCTlDPiJiWexXDw.png"><figcaption>Screenshot by Author</figcaption></figure><figure id="1bcf"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*8eVL-VMXHWWj-0Xmzh-npQ.png"><figcaption>Screenshot by Author</figcaption></figure><p id="33cc">Comparing the operations for creating a much larger grid, method 2 and 3 are clearly much more efficient than the first as well.</p><figure id="bf76"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*63s61uStmIz1I6hbHyhGUQ.png"><figcaption>Screenshot by Author</figcaption></figure><h2 id="341b">Final Note</h2><p id="5812">Beware of the difference and usages for shallow & deep copy as a wrong copy in data might lead to series error in production. For more on shallow and deep copy, refer to my previous article under Section <i>Copy: Shallow vs Deep.</i></p><div id="bc36" class="link-block"> <a href="https://readmedium.com/5-python-operations-that-confuse-beginners-92fafd51351c"> <div> <div> <h2>5 Python Operations that Confuse Beginners</h2> <div><h3>This article summarizes some highly similar Python operations that are easy to get mixed up with, especially for…</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*5SPYE5zmFLo8IYhdd3rHbw.png)"></div> </div> </div> </a> </div><p id="56b3">Thanks for reading and stay tuned for more articles on Python!</p></article></body>

Python List Multiplications — It’s a Trap!

An odd case I encountered while working on my project. I need a 3x3 grid represented by 2-dimensional array. To avoid typing the whole array by hand, list multiplications immediately came to mind.

So instead of writing:

arr = [[1, 1, 1], 
       [1, 1, 1], 
       [1, 1, 1]]

I initialized the array as follows:

arr = [[1] * 3] * 3

The list multiplication seemed so neat and simple at the time, until I ran into a problem later when trying to modify the values inside.

Changing value at 2nd row, 2nd column to zero: arr[1][1] = 0 , I was hoping to modity the grid as follows

arr = [[1, 1, 1], 
       [1, 0, 1], 
       [1, 1, 1]]

However, the array became as follows:

[[1, 0, 1], 
 [1, 0, 1], 
 [1, 0, 1]]

Explanation

The assignment arr[1][1] = 0 causing each row of the grid to change is because * in creation of the array is copying the address of the first dimension [1, 1, 1] . Instead of copying the items, list multiplication replicates references to the same item: a shallow copy. The list multiplication actually works in the first dimension but not the second:

lst = [1] * 3
lst[0] = 0
lst
>>> [0, 1, 1]

Other Possible Implementations

  • Nested for-loops
arr = [[1 for i in range(3)] for j in range(3)]
  • For loop with list multiplication in inner lists
arr = [[1] * 3 for i in range(3)]
  • List multiplication but with deep copy for inner lists, here lst[:] is used to obtain a deepcopy of the original array hence the return array won’t be affected by any changes in the original objects.
arr = [x[:] for x in [[1] * 3] * 3]

The 3rd method list multiplication turns out to be the fasted among all three, method 2 quite similar and method 1 being the slowest:

Screenshot by Author
Screenshot by Author

Comparing the operations for creating a much larger grid, method 2 and 3 are clearly much more efficient than the first as well.

Screenshot by Author

Final Note

Beware of the difference and usages for shallow & deep copy as a wrong copy in data might lead to series error in production. For more on shallow and deep copy, refer to my previous article under Section Copy: Shallow vs Deep.

Thanks for reading and stay tuned for more articles on Python!

Python
Data Structures
Recommended from ReadMedium