0

Developing a project I found a curious bug in Python. For example :

#Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)] on win32

variable = "Hello_1"
list = ["This is a variable -> ",variable]
print list #-> ["This is a variable -> " , "Hello_1"]

Now, I modify variable to a new value. So, I think when change the value of variable, I will see the new value in the list

variable = "Hello_2"
print list #-> ["This is a variable -> " , "Hello_1"]

But, the output is the same that first time? Does anybody know how to solve it?

Dhaval Jardosh
  • 7,151
  • 5
  • 27
  • 69
  • 2
    `variable` in the list is a copy; since its a primitive type, it is copied by value and not a "reference" as if it were an object. Also, don't name your `list`...list... – pstatix Jan 25 '18 at 15:35
  • 4
    There is no *dynamic* link between the list and the variable. Once the list is defined, any changes to the variable are not reflected back to the list. – Ma0 Jan 25 '18 at 15:35
  • 4
    To summarize: it's not a bug. General rule of thumb: if you think you've found a bug in the underlying programming language, you most likely haven't: check your code and your understanding first :) – bedwyr Jan 25 '18 at 15:37
  • 1
    @bedwyr Right, but assuming it is a bug in the beginning can be an incentive to try to understand what's going on and finally lead to assuming it's a misunderstanding :) – Alfe Jan 25 '18 at 15:40
  • 1
    @Alfe, agreed that the incentive to understand is an excellent thing. That said, I've seen many times where less knowledgeable developers assume a problem exists in the language, and then start trying to work around it :D – bedwyr Jan 25 '18 at 15:41
  • No, assuming it's a bug in the language takes the blame off the programmer, which is not the correct way to approach things. Assume it's *your* bug first. – SethMMorton Jan 25 '18 at 15:46

2 Answers2

1

See in picture variable has not any link with list.

enter image description here

str, int, float, and tuple are not editable. list and dictionary are editable. So if you use list or dictionary than it change every where.

See this example When Use list instead of variable

variable = ["Hello_1"]
lis = ["This is a variable -> ",variable]
print lis #-> ["This is a variable -> " , "Hello_1"]
variable[0] = "Hello_2"
print lis #-> ["This is a variable -> " , "Hello_2"]

enter image description here

it prints

['This is a variable -> ', ['Hello_2']]

Artier
  • 1,648
  • 2
  • 8
  • 22
-1

Python strings are pure values and when assigned, they are logically copied. (Maybe internally it is done smarter using some copy-on-write functionality, but to the Python developer this never shows.)

What you wanted is a reference to a string. This does not exist in Python.

The closest you can come to it is by using a list with a single element. Since lists are copied by reference, they can emulate what you expected:

variable = ["Hello_1"]
list = ["This is a variable -> ",variable]
print list #-> ["This is a variable -> " , ["Hello_1"]]
variable[0] = "Hello_2"  # assign to element of list
print list #-> ["This is a variable -> " , ["Hello_2"]]

But, please, since this is hard to understand code and far from being Pythonic, I posted this only to raise understanding of what's going on in Python. I would not recommend using this functionality, at least not for beginners. Better accept that strings are copied (at least logically) upon assignment and find a way to program what you need using this.

Alfe
  • 56,346
  • 20
  • 107
  • 159
  • Python strings aren't copied on assignment. But when assigning a new value to a variable, the reference is changed to point to that new value. Other references to the old value (e.g. the one in the list) are left alone. – das-g Jan 25 '18 at 15:47
  • @das-g I think you are wrong. Logically strings are copied upon assignment. After `a = b`, the value `b` represents is copied and `a` will hold that value, no matter what happens to `b`. If `b` is a complex term like `"abcde"[2:4]`, the logical copying becomes more obvious. I also wrote that internally the copying might be avoided but to the understanding of the programmer this is of no concern. – Alfe Jan 25 '18 at 15:56
  • Let me rephrase that: **No** python object is copied on assignment, no matter its type, no matter the Python implementation (as long as the implementation is compliant). Only the reference is being copied. As strings are immutable, this is difficult to tell apart from implementation-specific optimizations like interning / constant pooling and maybe other optimizations, that might be applied in some cases in some implementations but not in others. Use a mutable object (e.g. a list) and it becomes more apparent. If you do `a = b`, you are not just guaranteed that `a == b`, but also that `a is b` – das-g Jan 25 '18 at 23:01
  • With `"abcde"[2:4]`, at least conceptually, the new string object (if any) is created by the slicing, not by any assignment. For string copying, see https://stackoverflow.com/q/24804453/674064, https://stackoverflow.com/q/2123925/674064. For Python's reference semantics w.r.t. assignment, see https://stackoverflow.com/q/11222440/674064 – das-g Jan 25 '18 at 23:07
  • You will agree that `a = b` after `b = 5` will copy the value 5. I never said an *object* was copied. For objects, only references are passed. But for primitives (like numbers and strings) the values are copied, logically. – Alfe Jan 25 '18 at 23:39
  • "You will agree that a = b after b = 5 will copy the value 5." Sorry, I won't agree to that, nor will Python. Type `a is b` after that and get `True`. (Well, interning could also cause that outcome, but here's it's due to reference copying instead of value copying.) Other than in, say, Java, there are no "primitives" in Python. Everything\* in Python is an object. `isinstance(5, object)` will also give you `True`. * Well, everything that is accessible at runtime, AFAIK. So _almost_ everything. – das-g Jan 26 '18 at 00:25
  • (Though, I _do_ agree, that for immutable objects (such as Python strings or Python integers), this distinctions doesn't really matter for _most_ practical purposes.) – das-g Jan 26 '18 at 00:37
  • In my answer I concentrated on practical purposes because PO was obviously not very experienced. I don't see that this sort of language-lawyerism did any good *here*. But, so be it. – Alfe Jan 26 '18 at 00:55