# What is the difference between copy and deepcopy?

**URL:** <https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149>\
**Category:** General Usage\
**Tags:** deepcopy\
**Created:** [June 2, 2022, 7:51pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149 "2022-06-02T19:51:39Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Raymond](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raymond/32/36557_2.png) [@Raymond](https://discourse.julialang.org/u/Raymond)\
**Post date:** [June 2, 2022, 7:51pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/1 "2022-06-02T19:51:39Z")

</div>

Dear all,

I want to know the difference between `copy` and `deepcopy`?  
Many thanks.

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [June 2, 2022, 7:53pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/2 "2022-06-02T19:53:56Z")

</div>

> We should not encourage anybody to call deepcopy. It seems like the right thing if you’re just experimenting around with nested arrays and such, but it is almost never the right choice in real code, and using it is a sign that the design and data model needs to be thought through more. So really there is only copy, and the way to think about it is that it operates only on the object you pass it.

From [Should `copy` be renamed `shallowcopy`? · Issue #42796 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/42796#issuecomment-951232853)

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [June 2, 2022, 7:54pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/3 "2022-06-02T19:54:46Z")

</div>

```julia
julia> x = rand(4);

julia> xa = [x];

julia> copy(xa)[1] === x
true

julia> deepcopy(xa)[1] === x
false

```

---

<div class="post-metadata">

**Author:** ![Raymond](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raymond/32/36557_2.png) [@Raymond](https://discourse.julialang.org/u/Raymond)\
**Post date:** [June 2, 2022, 7:59pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/4 "2022-06-02T19:59:36Z")

</div>

> [@jar1](#):
>
> esign and data model needs to be thought through more.

Thanks for your suggestions.

---

<div class="post-metadata">

**Author:** ![Raymond](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raymond/32/36557_2.png) [@Raymond](https://discourse.julialang.org/u/Raymond)\
**Post date:** [June 2, 2022, 8:01pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/5 "2022-06-02T20:01:56Z")

</div>

Do you mean in your example, we should use `deepcopy` instead of `copy`?

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [June 2, 2022, 8:02pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/6 "2022-06-02T20:02:58Z")

</div>

No, I only showed the difference.

I agree that `copy` should be preferred.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [June 2, 2022, 8:14pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/7 "2022-06-02T20:14:56Z")

</div>

I think this example is more important to understand what copy does:

```julia
julia> struct example
       a::Vector{Int}
       end

julia> e=example([1,2,3])
example([1, 2, 3])

julia> e_copy=e # this is like copy, but copy isn't defined for struct example
example([1, 2, 3])

julia> e_copy.a[1]=100
100

julia> e
example([100, 2, 3])

```

You see, the vector inside the struct is the same object in `e` and `e_copy`. Change `a` in `e_copy` changes also `a` in `e`.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 2, 2022, 8:14pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/8 "2022-06-02T20:14:58Z")

</div>

If we need to copy nested structures like a Plots.jl `plot` object in order to modify inner properties, I think we have to use `deepcopy`.

Example:

```julia
using Plots
p1 = plot(sin, title = "old title")
p2 = deepcopy(p1) # copy would issue MethodError
p2[1][:title] = "new title"
plot(p1, p2)

```

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [June 2, 2022, 8:26pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/9 "2022-06-02T20:26:37Z")

</div>

> [@oheil](#):
>
> ```julia
> julia> e_copy=e # this is like copy, but copy isn't defined for struct example
> example([1, 2, 3])
> 
> ```

Maybe one can say this is true for `struct`s, but there is no behavior or code that gets executed upon assignment, unlike some other languages (e.g. `C++`) where this would call the copy constructor.

To add to my example:

```julia
julia> xa === xa
true

julia> copy(xa) === xa
false

```

meaning

```julia
julia> xb = xa;

julia> xc = copy(xa);

julia> xa[1] = rand(10);

julia> xa[1] === xb[1]
true

julia> xa[1] === xc[1]
false

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 2, 2022, 8:36pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/10 "2022-06-02T20:36:27Z")

</div>

A practical example, showing the difference:

```julia
x = [[0,1], [2,3]]
y = copy(x)
z = deepcopy(x)
x[2] .= [-2,-1]
y[2] # [-2,-1]
z[2] # [2,3]

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [June 2, 2022, 8:55pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/11 "2022-06-02T20:55:13Z")

</div>

I wanted to show what copy does for nested types.  
For OPs understanding it’s not important that deepcopy is not recommended or using of deepcopy is hinting on bad desing. OP wants to understand the difference of copy and deepcopy. @ rafael.guerra 's example shows the same without struct. It’s about nested objects and recursive copy (deepcopy) or shallow copy (copy).

---

<div class="post-metadata">

**Author:** ![blackeneth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blackeneth/32/10353_2.png) [@blackeneth](https://discourse.julialang.org/u/blackeneth)\
**Post date:** [June 3, 2022, 2:11am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/12 "2022-06-03T02:11:17Z")

</div>

I’ve never gotten why this functionality is preferred or useful.

Copy() is more like _alias_

DeepCopy() is actually _copy_

Why create a new variable that is just an alias? Just use the original.

When I make a copy (err, deepcopy) I want to leave the original alone and change the copy (err, deepcopy).

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [June 3, 2022, 2:34am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/13 "2022-06-03T02:34:19Z")

</div>

`copy` differs from alias:

```julia
julia> x = [1]
1-element Vector{Int64}:
 1

julia> y = copy(x)
1-element Vector{Int64}:
 1

julia> push!(x, 2)
2-element Vector{Int64}:
 1
 2

julia> x
2-element Vector{Int64}:
 1
 2

julia> y
1-element Vector{Int64}:
 1

```

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [June 3, 2022, 2:37am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/14 "2022-06-03T02:37:21Z")

</div>

But, if copy and deepcopy are equivalent, meaning there is no deep structure, do the two functions cost roughly the same? If so, I’d go with deepcopy.

---

<div class="post-metadata">

**Author:** ![brenhinkeller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brenhinkeller/32/36648_2.png) [@brenhinkeller](https://discourse.julialang.org/u/brenhinkeller)\
**Post date:** [June 3, 2022, 3:40am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/15 "2022-06-03T03:40:34Z")

</div>

To me `copy` is more like “`unalias` (aka, make a copy that specifically does not alias to the same memory), _but only one level deep_”

I also fully agree with the sentiment that if you find yourself frequently needing `deepcopy`, that probably suggests a suboptimal design / is a mild code smell (though I’m sure there are exceptions)

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 3, 2022, 4:24am UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/16 "2022-06-03T04:24:00Z")

</div>

Obviously a `Vector{Int}` isn’t going to be representative of all the flat data structures out there, but `deepcopy` seems to require more allocations and more time.

> **Expand example.**
>
> ```julia
> julia> x = collect(1:20);
> julia> @btime copy($x);
> 32.502 ns (1 allocation: 224 bytes)
> julia> @btime deepcopy($x);
> 123.883 ns (3 allocations: 560 bytes)
> julia> x = collect(1:20000);
> julia> @btime copy($x);
> 9.490 μs (2 allocations: 156.30 KiB)
> julia> @btime deepcopy($x);
> 10.579 μs (4 allocations: 156.62 KiB)
> 
> ```

I think the choice of `copy` vs `deepcopy` really only matters with objects that reference other objects, that’s where there can be 2 notions of a copy. `copy` is the more straightforward one: it makes a duplicate of an instance with the exact same content. The catch is, that content isn’t just data, there are also references to other objects. Therefore, the duplicate must _share_ referenced data with the original. `deepcopy` makes a duplicate with different references to recursively duplicated objects, so while all the references are different, the duplicate represents the same yet fully independent data as the original.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [June 3, 2022, 3:33pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/17 "2022-06-03T15:33:13Z")

</div>

Notice something interesting about your test: `deepcopy` apparently copies more than `copy`.  
The issue is not what gets copied, but that it is surprising to find that there is a difference. Hence,  
it is a good defensive move to use `deepcopy`, unless I know for sure that `copy` is good enough for my purpose.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [June 3, 2022, 3:45pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/18 "2022-06-03T15:45:30Z")

</div>

In particular, why are you copying? Presumably because you are going to modify something and don’t want that modification to affect the original. If you are going to make a modification, you know where you’re going to make that modification and only need to copy the thing that you’re going to modify. This is often at the outermost level, so copy is all you need. Sometimes it’s a level or two deeper, in which case deepcopy is overkill but might be more convenient than arranging copies down to the rigth level.

---

<div class="post-metadata">

**Author:** ![DoktorMike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/doktormike/32/2736_2.png) [@DoktorMike](https://discourse.julialang.org/u/DoktorMike)\
**Post date:** [June 3, 2022, 5:24pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/19 "2022-06-03T17:24:38Z")

</div>

I agree, in machine learning i have always found that people run into bugs when copying models for example. You almost never want copy there but deepcopy instead. As such i would have preferred `copy=deepcopy` and `shallowcopy=copy`. I understand why it is not so but in my line of work it would have simplified things. 🙂

This is not a Julia thing though, we have the same issues popping up in python too. It also seems pretty uncontentious to use `copy` the way it’s currently implemented in Julia.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [June 3, 2022, 5:48pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149/20 "2022-06-03T17:48:50Z")

</div>

> [@DoktorMike](#):
>
> in machine learning i have always found that people run into bugs when copying models for example. You almost never want copy there but deepcopy instead.

This is precisely why it’s nice (but also a little fraught) to allow the model or object itself to define what `copy` should do and what constitutes its “outer structure.” Perhaps `copy(::DeepLearningModel)` should indeed make a copy of all the arrays it holds that define its weights because those are the things you modify _directly_ when calling `train!(::DeepLearningModel)`? That is, for example, exactly [what AlphaZero does](https://github.com/jonathan-laurent/AlphaZero.jl/blob/9de68d9488d9ad51ebcc490884b880dbd98e148b/src/networks/architectures/simplenet.jl#L68-L76).

[Next page](https://discourse.julialang.org/t/what-is-the-difference-between-copy-and-deepcopy/82149.md?page=2)
