Differences Between Vectors and Tuples in Julia
Description
Vectors and tuples may appear similar at first glance, and they indeed share several common points, which might lead one to think, "Are they just the same concept with different names?" However, there are a few important differences between vectors and tuples.
This article will primarily focus on the similarities and differences from the perspective of writing and using code. The mathematical basis for tuples in Julia and how they differ from vectors (lists) are detailed in the book Julia Programming in $3.2.2$.
Commonalities
The only commonalities between vectors and tuples are that they can contain multiple elements and support indexing and slicing.
Elements
Both vectors and tuples can contain multiple elements.
julia> v = [1, 2, 3]
3-element Vector{Int64}:
1
2
3
julia> t = (1, 2, 3)
(1, 2, 3)
Indexing
Both vectors and tuples allow for accessing elements through indexing.
julia> v[1]
1
julia> t[1]
1
Slicing
Both vectors and tuples support slicing.
julia> v[1:2]
2-element Vector{Int64}:
1
2
julia> t[1:2]
(1, 2)
Differences
Immutability
Tuples are immutable. That is, the elements of a tuple cannot be changed.
julia> v[1] = 10
10
julia> v
3-element Vector{Int64}:
10
2
3
julia> t[1] = 10
ERROR: MethodError: no method matching setindex!(::Tuple{Int64, Int64, Int64}, ::Int64, ::Int64)
Notation
Vectors are denoted using square brackets []
, while tuples use parentheses ()
. Commas can be omitted in vectors, but not in tuples. In fact, parentheses can be omitted in tuples. Also, omitting commas in vectors results in a row vector.
julia> [1 2 3]
1×3 Matrix{Int64}:
1 2 3
julia> (1 2 3)
ERROR: ParseError:
# Error @ REPL[16]:1:4
(1 2 3)
# └─┘ ── Expected `)`
julia> 1, 2, 3
(1, 2, 3)
Shape
Vectors can change shape, but tuples cannot.
julia> u = [1, 2, 3, 4, 5, 6]
6-element Vector{Int64}:
1
2
3
4
5
6
julia> reshape(u, 1, 6)
1×6 Matrix{Int64}:
1 2 3 4 5 6
julia> reshape(u, 2, 3)
2×3 Matrix{Int64}:
1 3 5
2 4 6
julia> reshape(u, 3, 2)
3×2 Matrix{Int64}:
1 4
2 5
3 6
julia> reshape(t, 3, 1)
ERROR: MethodError: no method matching reshape(::Tuple{Int64, Int64, Int64}, ::Int64, ::Int64)
Speed1
Tuples are faster than vectors because they are immutable. Therefore, using tuples is advantageous when there is no need to change elements and the number of elements is small. Conversely, vectors are much more beneficial in situations where the size is large.
julia> using BenchmarkTools
julia> @benchmark (1, 2, 3)
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
Range (min … max): 0.700 ns … 5.600 ns ┊ GC (min … max): 0.00% … 0.00%
Time (median): 0.700 ns ┊ GC (median): 0.00%
Time (mean ± σ): 0.741 ns ± 0.099 ns ┊ GC (mean ± σ): 0.00% ± 0.00%
█ ▂
█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▂
0.7 ns Histogram: frequency by time 0.8 ns <
Memory estimate: 0 bytes, allocs estimate: 0.
julia> @benchmark [1, 2, 3]
BenchmarkTools.Trial: 10000 samples with 999 evaluations.
Range (min … max): 13.514 ns … 1.907 μs ┊ GC (min … max): 0.00% … 98.16%
Time (median): 16.817 ns ┊ GC (median): 0.00%
Time (mean ± σ): 20.538 ns ± 64.293 ns ┊ GC (mean ± σ): 12.68% ± 4.04%
▄▄█▄▆▁▁
▂▂▃▃▆▇███████▆▆▄▄▃▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▃▃▃▃▂▂▂▂▂▂▁▂▂ ▃
13.5 ns Histogram: frequency by time 34.1 ns <
Memory estimate: 80 bytes, allocs estimate: 1.
Type Promotion
Type promotion is automatically applied when defining vectors, but not with tuples. When defining vectors and tuples with 1
and 2.0
, the vector’s elements will align to Float64
.
julia> [1, 2.0]
2-element Vector{Float64}:
1.0
2.0
julia> Any[1, 2.0]
2-element Vector{Any}:
1
2.0
julia> (1, 2.0)
(1, 2.0)
Bogumił Kamiński, 데이터 분석을 위한 줄리아(Julia for Data Analysis, 류현지 역), p88 ↩︎