Python question -- List

788
8
Jump to solution
08-03-2022 07:33 AM
YinghongLi1
Occasional Contributor

I created a list variable and assigned another variable to it.  Then i modified the 2nd by adding a new item to it.  I found out the 1st variable changed too.  Just want to confirm that assignment does not create a new list.

list1=["v1", "v2"," v3"]

list2=list1

list2.insert[0, "id"]

so list2 output is: ["id", "v1", "v2"," v3"]

however list1 output is the same.

So i can't use assignment to create a new list from list1.  rather i need to do this:

list1=["v1", "v2"," v3"]

list2=["id", "v1", "v2"," v3"]

i'd like to understand this better but i did not anything by searching online.  Help please.  Thanks.

0 Kudos
2 Solutions

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

UPDATE:  I misread the original question, so the OP is seeing the expected behavior.

If you want to make a copy of a list, there are numerous ways.  One common way is to use a list comprehension:

 

 

Type "help", "copyright", "credits" or "license" for more information.
>>> list1=["v1", "v2"," v3"]
>>> list2 = [i for i in list1]
>>> list2.insert(0, "id")
>>> list1
['v1', 'v2', ' v3']
>>> list2
['id', 'v1', 'v2', ' v3']
>>>

 

Another way is to use copy — Shallow and deep copy operations — Python 3.10.6 documentation

Python 3.7.11 [MSC v.1927 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import copy
>>> list1=["v1", "v2"," v3"]
>>> list2 = copy.copy(list1)
>>> list2.insert(0, "id")
>>> list1
['v1', 'v2', ' v3']
>>> list2
['id', 'v1', 'v2', ' v3']
>>>

 

View solution in original post

DanielBrumm1
Occasional Contributor II

list1 = ["v1", "v2"," v3"]
list2 = list1.copy()
list2.insert(0, "id")

print(list1)
print(list2)

 

['v1', 'v2', ' v3']
['id', 'v1', 'v2', ' v3']
Daniel Brumm
GIS Nerd

View solution in original post

8 Replies
JoshuaBixby
MVP Esteemed Contributor

For starters, you have some invalid code so I am not sure how you are testing.  For example,

>>> list2.insert[0, "id"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'builtin_function_or_method' object is not subscriptable

Changing the code to proper syntax, I get the expected results in Python 3.7.11 bundled with ArcGIS Pro 2.9.x

Python 3.7.11 [MSC v.1927 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> list1=["v1", "v2"," v3"]
>>> list2=list1
>>> list2.insert(0, "id")
>>> list1
['id', 'v1', 'v2', ' v3']
>>> list2
['id', 'v1', 'v2', ' v3']
>>>
JoshuaBixby
MVP Esteemed Contributor

UPDATE:  I misread the original question, so the OP is seeing the expected behavior.

If you want to make a copy of a list, there are numerous ways.  One common way is to use a list comprehension:

 

 

Type "help", "copyright", "credits" or "license" for more information.
>>> list1=["v1", "v2"," v3"]
>>> list2 = [i for i in list1]
>>> list2.insert(0, "id")
>>> list1
['v1', 'v2', ' v3']
>>> list2
['id', 'v1', 'v2', ' v3']
>>>

 

Another way is to use copy — Shallow and deep copy operations — Python 3.10.6 documentation

Python 3.7.11 [MSC v.1927 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import copy
>>> list1=["v1", "v2"," v3"]
>>> list2 = copy.copy(list1)
>>> list2.insert(0, "id")
>>> list1
['v1', 'v2', ' v3']
>>> list2
['id', 'v1', 'v2', ' v3']
>>>

 

Luke_Pinner
MVP Regular Contributor

list2 = list1[:] also works.

0 Kudos
DanielBrumm1
Occasional Contributor II

list1 = ["v1", "v2"," v3"]
list2 = list1.copy()
list2.insert(0, "id")

print(list1)
print(list2)

 

['v1', 'v2', ' v3']
['id', 'v1', 'v2', ' v3']
Daniel Brumm
GIS Nerd
JoshuaBixby
MVP Esteemed Contributor

Nice catch, I forgot that lists had a copy method because I never use it.  list.copy() is a shallow copy like when using copy.copy(), but it is definitely cleaner.

I_AM_ERROR
Occasional Contributor

Just to add context, assigning a new variable to an existing object is just creating an additional pointer to your existing list. The list already exists in memory, you just have two name for it now instead of one. 

You can check by using id(var) and id(var2) for example. They'll point to the same memory address if you do something like:

var = "test"
var2 = var

 

JoshuaBixby
MVP Esteemed Contributor

The situation is more nuanced because immutable and mutable Python objects are handled differently.  For strings, which are immutable, var and var2 don't reference the same memory once either variable is updated while that isn't the case for lists that are mutable. 

Python 3.7.11 [MSC v.1927 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> var = "test"
>>> id(var)
1966892852656
>>> var2 = var
>>> id(var2)
1966892852656
>>> var2 = "hello"
>>> id(var2)
1966901122480
>>>
>>> var
'test'
>>> var2
'hello'
>>>
>>> list1 = ["v1", "v2", "v3"]
>>> id(list1)
1966862258632
>>> list2 = list1
>>> id(list2)
1966862258632
>>> list2.insert(0, "id")
>>> id(list2)
1966862258632
>>>
>>> list1
['id', 'v1', 'v2', 'v3']
>>> list2
['id', 'v1', 'v2', 'v3']
>>>
I_AM_ERROR
Occasional Contributor

Was not aware of this, thanks!

0 Kudos