ジュリアでの集合データ型と演算子
概要
Juliaでは、Pythonと同様にセットデータ型をサポートしています。元来のセットデータ型がそうであるように、使用する人にとっては非常に便利で、使用しない人にはまったく使われないものですが、Juliaは言語設計自体が数学に近いため、セットの概念と操作がしっかりと実装されており、必ず理解しておくべきです。 特に、他の言語、特にPythonと最も異なる点は、ユニコード記号もコードの一部として使用できることです。AtomエディタでJunoを使用している場合、上記のようにTeXコードを自動補完することができます。このコンテキストでは、$\in$は単なる記号ではなく、実際に要素がセットに属しているかを表しています。
コード
julia> X = Set([1,2,3,1]); print(X)
Set([2, 3, 1])
julia> X[1]
ERROR: MethodError: no method matching getindex(::Set{Int64}, ::Int64)
Stacktrace:
[1] top-level scope at REPL[23]:1
julia> for i in X print(i) end
231
上記のコードは、セット $X$ を $X := \left\{ 1, 2, 3, 1 \right\} = \left\{ 2,3,1 \right\}$ として定義することを意味します。数学でのセットと同じように、重複と順序の概念は存在しません。したがって、最初のインデックスを参照するとエラーが出ます。しかし、データ型自体はPythonと同様にイテラブルであるため、ループ内で使用することができます。
julia> if 1∈X print("!") else print("?") end
!
julia> if 0∈X print("!") else print("?") end
?
julia> if 0∉X print("!") else print("?") end
!
julia> if [1,2] ⊆ X print("!") else print("?") end
!
julia> if [0,1,2] ⊆ X print("!") else print("?") end
?
これが数式を読むような親しみを感じるなら、セットデータ型を有効に使用する準備ができていることです。特に注意すべき点は、上記のような計算がセットデータ型に限定されて動作するわけではないことです。つまり、リストに対しても同様の操作を気軽に使用することができます。セットデータ型が不慣れであっても、セットにだけ慣れていれば、Juliaのセット演算子を利用することに問題はありません。なお、包含関係は \subset $\subset$ ではなく \subseteq $\subseteq$ を使用する必要があります。
julia> Y = ["1","2",3]
3-element Array{Any,1}:
"1"
"2"
3
julia> ∪(X,Y)
Set{Any} with 5 elements:
"1"
2
3
"2"
1
julia> ∩(X,Y)
Set{Int64} with 1 element:
3
julia> ∩(Y,X)
1-element Array{Any,1}:
3
julia> setdiff(X,Y); X
Set{Int64} with 3 elements:
2
3
1
julia> setdiff!(X,Y); X
Set{Int64} with 2 elements:
2
1
基本的にセットを扱うため、和集合と交差点も数式と同様に表現することができます。2行目と3行目の違いは操作の順序です。$X$ はJuliaでセットデータ型、$Y$はただの配列として定義されており、返される値は最初の引数のデータ型に従います。このような違いは、Juliaのような強い型付け言語では非常に重要であるため、必ず理解しておく必要があります。差集合は、setdiff()
はただの差集合を返し、setdiff!()
はセット自体を更新するという違いがあります。
環境
- OS: Windows
- julia: v1.5.0