5 ms·
TL;DR is that multiplying a list performs a shallow copy of the list's elements. Great article. The only thing it's missing is a snippet that shows what you sho
by 10000truths 3y ago
TL;DR is that multiplying a list performs a shallow copy of the list's elements. Great article. The only thing it's missing is a snippet that shows what you should do instead:
[[] for _ in range(N)]
Since generator-like expressions evaluates the inner expression (i.e. the []) on each iteration, the elements of the outer list are guaranteed to be unique references.
- blt 3y agoThis is pretty subtle. I wish more languages explicitly distinguished references and values like C++ and Rust.
- scbrg 3y agoEverything falls in place when you accept that in python all names (including list indexes) are just pointers to an object, and objects aren't copied unless you explicitly copy them. Everything else follows from that. If you had done [1] * 4 you'd ended up with a list of four references to the same object (1) as well. It's just that 1 isn't mutable, so nobody cares.
- deleted 3y ago[deleted]
- bmitc 3y agoF# does this nicely with the mutable keyword and the <- assignment operator.
- Skeime 3y agoIn Python, everything is a reference, so you don't need special syntax to mark them. There just happen to be some types where you cannot change the referenced value in any way. These behave like value types in other languages. (If you believe that they should be marked explicitly, do you also believe the same thing about Rust? I.e. should the Rust compiler throw an error if you never actually change a reference type, as you "should" be using a value type in that case?)
- drones 3y agoI only use the [x] * n form of array initialization for primitive types (int,float,bool,string). So #good a = [True] * 8 # bool is primitive b = [[True] * 8 for i in range(8)] # range creates new lists each time #bad a = [{}] * 8 # dict is not a primitive b = [[True] * 8] * 8 # list is not a primitive