How create a new deep copy (clone) of a ListT?
You need to create new Book
objects then put those in a new List
:
List<Book> books_2 = books_1.Select(book => new Book(book.title)).ToList();
Update: Slightly simpler... List<T>
has a method called ConvertAll
that returns a new list:
List<Book> books_2 = books_1.ConvertAll(book => new Book(book.title));
Deep copy of ListT
The idiomatic way to approach this in C# is to implement ICloneable
on your Data
, and write a Clone
method that does the deep copy (and then presumably a Enumerable.CloneRange
method that can clone part of your list at once.) There isn't any built-in trick or framework method to make it easier than that.
Unless memory and performance are a real concern, I suggest that you try hard to redesign it to operate on immutable Data
objects, though, instead. It'll wind up much simpler.
Is there any better deep clone methods for list?
That's not a real deep-copy because the Card
instances are still the same, only the list is different. You could have this much simpler:
List<Card> cloneList = cards.ToList();
You need to "copy" all properties of the Card
instances as well:
public List<Card> Copy(List<Card> cards)
{
List<Card> cloneList = new List<Card>();
foreach (var card in cards)
{
Card clone = new Card();
clone.Property1 = card.Property1;
// ... other properties
cloneList.Add(clone);
}
return cloneList;
}
You could also provide a factory method that creates a clone of a given Card
instance:
public class Card
{
// ...
public Card GetDeepCopy()
{
Card deepCopy = new Card();
deepCopy.Property1 = this.Property1;
// ...
return deepCopy;
}
}
Then you have encapsulated this logic in one place where you can even access private
members(fields, properties, constructors). Change the line in the Copy
method above to:
cloneList.Add(card.GetDeepCopy());
How to deep copy a list?
E0_copy
is not a deep copy. You don't make a deep copy using list()
. (Both list(...)
and testList[:]
are shallow copies.)
You use copy.deepcopy(...)
for deep copying a list.
deepcopy(x, memo=None, _nil=[])
Deep copy operation on arbitrary Python objects.
See the following snippet -
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b # b changes too -> Not a deepcopy.
[[1, 10, 3], [4, 5, 6]]
Now see the deepcopy
operation
>>> import copy
>>> b = copy.deepcopy(a)
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 10, 3], [4, 5, 6]]
>>> a[0][1] = 9
>>> a
[[1, 9, 3], [4, 5, 6]]
>>> b # b doesn't change -> Deep Copy
[[1, 10, 3], [4, 5, 6]]
To explain, list(...)
does not recursively make copies of the inner objects. It only makes a copy of the outermost list, while still referencing the same inner lists, hence, when you mutate the inner lists, the change is reflected in both the original list and the shallow copy. You can see that shallow copying references the inner lists by checking that id(a[0]) == id(b[0])
where b = list(a)
.
deep copy of list in python
Your code does indeed succeed in creating a shallow copy. This can be seen by inspecting the IDs of the two outer lists, and noting that they differ.
>>> id(l)
140505607684808
>>> id(x)
140505607684680
Or simply comparing using is
:
>>> x is l
False
However, because it is a shallow copy rather than a deep copy, the corresponding elements of the list are the same object as each other:
>>> x[0] is l[0]
True
This gives you the behaviour that you observed when the sub-lists are appended to.
If in fact what you wanted was a deep copy, then you could use copy.deepcopy
. In this case the sublists are also new objects, and can be appended to without affecting the originals.
>>> from copy import deepcopy
>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> xdeep = deepcopy(l)
>>> xdeep == l
True
>>> xdeep is l
False <==== A shallow copy does the same here
>>> xdeep[0] is l[0]
False <==== But THIS is different from with a shallow copy
>>> xdeep[0].append(10)
>>> print(l)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> print(xdeep)
[[1, 2, 3, 10], [4, 5, 6], [7, 8, 9]]
If you wanted to apply this in your function, you could do:
from copy import deepcopy
def processed(matrix,r,i):
new_matrix = deepcopy(matrix)
new_matrix[r].append(i)
return new_matrix
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
x = processed(l,0,10)
print(x)
print(l)
If in fact you know that the matrix is always exactly 2 deep, then you could do it more efficiently than using deepcopy
and without need for the import
:
def processed(matrix,r,i):
new_matrix = [sublist[:] for sublist in matrix]
new_matrix[r].append(i)
return new_matrix
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
x = processed(l,0,10)
print(x)
print(l)
How do I clone a generic list in C#?
You can use an extension method.
static class Extensions
{
public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
}
How to make a deep copy of an object with a List variable in Java?
Your copy constructors are just doing shallow copies of each field. That's fine for strings because they're immutable, and it's fine for ints because they're primitive (which means they lack identity and are immutable). In those cases, there is no important difference between shallow and deep copies. But it doesn't work in general for lists because lists can be mutable and so can their elements. So instead of just pointing at the same list, you need to make a new list and deep copy each element of the original list into the new one.
Use this helper method to make deep copies of any lists:
static <T> List<T> deepCopyList(List<T> list, UnaryOperator<T> deepCopyElement) {
return list.stream().map(deepCopyElement).collect(
Collectors.toCollection(ArrayList::new)
);
}
Like so:
public AtomDTO(AtomDTO that) {
this(that.getName(), that.getType(), deepCopyList(that.getBonds(), BondDTO::new));
}
how to make a deep copy of my list
You can create an extension method where you serialize the object only to deserialize it again. This will create a new object with it's own references, thus a Deep Copy.
Public Module Extensions
<System.Runtime.CompilerServices.Extension()> _
Public Function DeepCopy(Of T)(ByVal Obj As T) As T
If Obj.GetType().IsSerializable = False Then Return Nothing
Using MStream As New MemoryStream
Dim Formatter As New BinaryFormatter
Formatter.Serialize(MStream, Obj)
MStream.Position = 0
Return DirectCast(Formatter.Deserialize(MStream), T)
End Using
End Function
End Module
Now you can just call:
Dim network As List(Of train) = per_network.DeepCopy()
EDIT:
These are the required imports for my code above:
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Related Topics
Why Do I Get an Outofmemoryexception When I Have Images in My Listbox
What Is the Effect of Asenumerable() on a Linq Entity
Disable JavaScript Error in Webbrowser Control
Serialization of Entity Framework Objects with One to Many Relationship
Disable Mouse Wheel on Itemscontrol in Wpf
How to Configure Swashbuckle to Ignore Property on Model
Data Binding in Wpf User Controls
Send Email Using System.Net.Mail Through Gmail
Datacontract Xml Serialization and Xml Attributes
Docking Window Inside Another Window
Best Way to Tackle Global Hotkey Processing in C#
How to Get the "Friendly" Os Version Name
Refresh Datagridview When Updating Data Source
How to Make the Return Type of a Method Generic
Replace Only Some Groups with Regex
How to Verify Text Is Bold Using Selenium on an Angular Website with C#