This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 3 years ago.
I am using Python 3.6
I have a list:
listA = [1,2,3,1,2,4]
I am trying to remove the repetitive items from the list, so the final list will be
listA = [3,4]
After I loop once and remove 1s from the list using pop, my loop automatically advances to 3, instead of 2.
To avoid this, I used following logic:
ListB= ListA
ListA.clear()
ListA = ListB
but once I clear ListA, the other list ListB is also getting cleared automatically. How can I avoid this or solve this issue?
Objects in Python are stored by reference,which means you didn't assign the value of ListA to ListB, but a pointer to the object.You can use is operator to test if two objects have the same address in memory.
Sequences can be copied by slicing so you can use this to copy a list:
b = a[:]
Also you can use
b = list(a)
Or you can use copy() module:
from copy import copy
b = copy(a)
See more details from How do I copy an object in Python?
Names of lists in python are actually just references so your new list is a reference to the same list. To actually make a new list you can use
ListB = list(ListA)
Related
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 8 years ago.
I wanted to efficiently set a bunch of variables to an empty list. However, using this method, operations on one variable seem to apply to all:
>>> r1,r2,r3,r4,r5,r6,r7,r8=[[]]*8
>>> r1
[]
>>> r1+=[2]
>>> r1,r2
([2], [2])
Why is this? Also, what is the most efficient method that leaves each variable independent?
Doing [[]]*8 creates a list of eight references to the same list object. That is why they all get affected when you update one. To make eight unique lists, use a generator expression:
r1,r2,r3,r4,r5,r6,r7,r8 = ([] for _ in range(8))
You might also use a list comprehension:
r1,r2,r3,r4,r5,r6,r7,r8 = [[] for _ in range(8)]
This question already has answers here:
How do I concatenate two lists in Python?
(31 answers)
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 5 months ago.
x=[1,2,3]
x.extend('a')
Output:
x is [1,2,3,'a']
But when I do the following:
[1,2,3].extend('a')
Output:
None
Why does extend work on a list reference, but not on a list?
2nd Part:
I found this because I was trying to append a listB to a listA while trying to extend listC to listB.
listA.append([listB[15:18].extend(listC[3:12])])
Supposing lists cannot be directly appended / extending. What is the most popular work around form for resolving this issue?
list.extend modifies the list in place and returns nothing, thus resulting in None. In the second case, it's a temporary list that is being extended which disappears immediately after that line, while in the first case it can be referenced via x.
to append a listB to a listA while trying to extend listC to listB.
Instead of using extend, you might want to try this:
listA.append(listB[15:18] + listC[3:12])
Or do it in multiple simple lines with extend if you want to actually modify listB or listC.
extend will extend list it self. Return type of that method is None
If you want to union 2 list and add that list to another list then you have to use another way to add.
listB[15:18] = listC[3:12]
listA.extend(listB)
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Why does this code for initializing a list of lists apparently link the lists together? [duplicate]
(1 answer)
Closed 8 years ago.
I have a list that needs to contain a variable number of independent sets.
When I run the following piece of code, I want to add the string "testing" to only the first set.
numberOfSets = 3
test = [set()]*numberOfSets
test[0].add("testing")
print test
However, when I print test, it shows three identical sets that all contain testing. How can I set up my list so I can separately access each set?
When you do [set()]*3, you create three sets that reference the same object, thus when you change one value, the others change. Use a list comprehension here instead:
>>> numberOfSets = 3
>>> test = [set() for _ in xrange(numberOfSets)]
>>> test[0].add("testing")
>>> print test
[set(['testing']), set([]), set([])]
You can do
test = [set() for _ in xrange(numberOfSets)] # use 'range' in Python 3.x
[set()]*x creates a list with x of the same set instance, whereas the comprehension above creates a new, independent set on each iteration, as desired.
In general, you should be very cautious whenever you multiply lists whose elements are mutable.
This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 9 years ago.
I am trying to get an element from list and make some change on this element (which is also a list). Weirdly, the change applied on the previous list. Here is my code:
>>>sentences[0]
['<s>/<s>',
'I/PRP',
'need/VBP',
'to/TO',
'have/VB',
'dinner/NN',
'served/VBN',
'</s>/</s>']
>>>sentence = sentences[0]
>>>sentence.insert(0,startc); sentence.append(endc)
>>>sentences[0]
['<s>/<s>',
'<s>/<s>',
'I/PRP',
'need/VBP',
'to/TO',
'have/VB',
'dinner/NN',
'served/VBN',
'</s>/</s>'
'</s>/</s>']
It is like I just got a pointer to that element, not a copy
You do get a "pointer", in fact. Lists (and any mutable value type!) are passed around as reference in Python.
You can make a copy of a list by passing it to the list() object constructor, or by making a full slice using [:].
a = [1,2,3]
b = a
c = list(a)
d = a[:]
a[1] = 4 # changes the list referenced by both 'a' and 'b', but not 'c' or 'd'
You're exactly right! In Python, when you pass a list as an argument to a function, or you assign a list to another variable, you're actually passing a pointer to it.
This is for efficiency reasons; if you made a separate copy of a 1000-item list every time you did one of the aforementioned things, the program would consume way too much memory and time.
To overcome this in Python, you can duplicate a one-dimensional list using = originalList[:] or = list(originalList):
sentence = sentences[0][:] # or sentence = list(sentences[0])
sentence.insert(0,startc)
sentence.append(endc)
print(sentence) # modified
print(sentences[0]) # not modified
Consider using list comprehension if you need to duplicate a 2D list.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python list confusion
When I write a simple python script, I define a new list as follows:
A=[[],]*10
What I wanna do is just initialize a list whose length is 10 and each element is a empty list.
And when I do something like:
A[0].append(["abc",])
I just wanna append this ["abc",] to A[0], and it turn out to be that every elements in A is appended with ["abc",]
I know this probably due to my initialization (A=[[],]*10) . I just want to know why this happened.
Your expression A=[[]]*10 is equivalent to:
a = []
A = [a]*10
This means that A consists of 10 references to one and the same list.
You are creating a list with 10 references to the same empty list.
You should use a list comprehension instead:
A = [[] for _ in range(10)]
In a list comprehension, you create a new list for every iteration through the loop. If you are using python 2, you should use xrange instead of range (although with only 10 elements that won't make much difference).
All the empty lists are references to the same object.