1

When I do:

cand = [ [ 0, 0 ] ] * 4

followed by:

cand[0][0] = 99

I get:

[[99, 0], [99, 0], [99, 0], [99, 0]]

does the multiplication simply copy list references? Is there a way to have distinct lists?

fusha
  • 363
  • 3
  • 9
  • definitely a duplicate – jamylak Apr 26 '13 at 00:53
  • 1
    This may be of interest http://bugs.python.org/issue12597 – HennyH Apr 26 '13 at 00:55
  • @HennyH "Resolution: invalid" – user2246674 Apr 26 '13 at 01:06
  • @fusha The post answered the question you asked. So start with a question that hasn't been answered. – user2246674 Apr 26 '13 at 01:07
  • @user2246674 I linked that page, as they discussed the topic, whether or not it was a bug, why it was happening and a way around it. – HennyH Apr 26 '13 at 01:10
  • @user2246674, do I need to find new questions all the time? what kind of a motivation is that? – fusha Apr 26 '13 at 01:22
  • @fush look we can't blame you for this problem, every python programmer runs into this and it's impossible to search for, however the answer to your question is yes! you need to see if your question has already been answered. What does that even have to do with motivation??? – jamylak Apr 26 '13 at 02:07
  • @jamylak, no I'm grateful that I have my answer. I was referring to the suggestion of starting with a question that hasn't been answered. – fusha Apr 26 '13 at 02:11
  • @fusha If it is verified that X happens, don't ask if X happens. It does, as stated. Instead, ask *why* X happens or how to *prevent* X from happening etc. – user2246674 Apr 26 '13 at 04:03

1 Answers1

4

It creates four references to the same object. To get around that, you have to create four separate lists:

cand = [[0, 0] for _ in range(4)]
Blender
  • 289,723
  • 53
  • 439
  • 496
  • thanks, what good is list multiplication then? I have to change all my code :(( – fusha Apr 26 '13 at 00:57
  • also, is there a way to create distinct lists after multiplication? like: `cand = copy([ [ 0, 0 ] ] * 4)` which of course doesn't work. – fusha Apr 26 '13 at 01:01
  • @fusha: You'd have to do `[copy(l) for l in cand]`. As for the usefulness of `*`, it's not specific to lists. It works for tuples as well, which are immutable and don't have that problem. – Blender Apr 26 '13 at 01:05
  • @fusha possibly `[deepcopy(l) for l in cand]` depending on if you have nested list copies. The answer to your question about what good is list multiplication... when you find yourself working with lists like this, or matrices, you should be using `numpy` – jamylak Apr 26 '13 at 02:10
  • @jamylak, thanks again, I just can't think of a scenario that duplicating references would come handy. – fusha Apr 26 '13 at 02:22
  • @fusha: I do remember one concrete use case, but I don't actually remember what it is. It's a lot more useful for immutable objects. – Blender Apr 26 '13 at 02:34
  • @fusha The point is that Python doesn't do any *magic*. I would be surprised if Python went ahead and deep copied every object without me knowing, which could take a lot of time for huge lists. (The principle of least astonishment). – jamylak Apr 26 '13 at 02:47