Ко

Кортежі у Julia

1 вправа

Про концепцію Кортежі

Tuple багато в чому досить схожий на Vector (одновимірний array). Однак є кілька важливих відмінностей.

  • Кортежі записують у круглих дужках ( ), а не в квадратних [ ], хоча дужки можна опускати, коли зміст однозначний.
  • Кортежі не обовʼязково мають бути однорідними: тип кожного елемента зберігається окремо.
  • Кортежі незмінні.

Незмінність дає компілятору більше можливостей для оптимізації та робить кортежі продуктивнішими за вектори, тож їм варто віддавати перевагу там, де змінність не потрібна.

julia> t = (3, 5.2, "xyz")
(3, 5.2, "xyz")

# Non-homogeneous:
julia> dump(t)
Tuple{Int64, Float64, String}
  1: Int64 3
  2: Float64 5.2
  3: String "xyz"

julia> t[2]
5.2

# Immutable:
julia> t[2] = 7.3
ERROR: MethodError: no method matching setindex!(::Tuple{Int64, Float64, String}

Існує також конструктор Tuple(), який перетворює будь-яку ітеровану колекцію на кортеж. Зручно те, що він розглядає рядок тексту (англ. string) як ітеровану колекцію символів.

julia> Tuple("Julia")
('J', 'u', 'l', 'i', 'a')

Для будь-якого кортежу можна отримати доступ до елементів за індексом або перебрати їх у циклі.

Будь-який суто числовий кортеж можна також використовувати в математичних функціях, як-от sum(), точно так само, як масиви.

Розпакування

Кортеж можна розпакувати на окремі елементи за допомогою множинного присвоєння. Для елементів, які не потрібні, використаймо підкреслення _ як фіктивну змінну.

julia> tup = (1, "Julia", true)
(1, "Julia", true)

julia> num, name, _ = tup
(1, "Julia", true)

julia> uppercase(name), 2num
("JULIA", 2)

Щоб скопіювати всі елементи кортежу в інший кортеж (або, загалом, у колекцію), існує оператор splat ..., який його розпаковує. Докладніше про це йтиметься в концепції Функції.

julia> new_tup = (tup..., π, '😊')
(1, "Julia", true, π, '😊')

Іменовані кортежі

Tuple містить лише значення. NamedTuple зіставляє кожне значення з іменем.

Окремі поля тоді можна отримати через «точкову» нотацію:

julia> nt = (a = 1, b = 7.3)
(a = 1, b = 7.3)

julia> dump(nt)
@NamedTuple{a::Int64, b::Float64}
  a: Int64 1
  b: Float64 7.3

julia> nt.b
7.3

Імʼя всередині зберігається як Symbol (незмінний тип, а перед іменем ставиться двокрапка :), тому доступний альтернативний синтаксис:

julia> nt[:b]
7.3

Іноді корисно розділити створення іменованого кортежу на два кроки:

  1. Визначити поля як власний тип даних.
  2. Використати його як конструктор, щоб перетворити кортеж на іменований кортеж.
# Step 1
julia> Student = NamedTuple{(:name, :grade), Tuple{String, Int}}
@NamedTuple{name::String, grade::Int64}

julia> typeof(Student)
DataType

# Step 2
julia> s = Student( ("Helen", 3) )
(name = "Helen", grade = 3)

julia> dump(s)
@NamedTuple{name::String, grade::Int64}
  name: String "Helen"
  grade: Int64 3

Існує напрочуд багато інших способів створити іменований кортеж, тож за бажанням зазирнімо до документації.

Легко отримати окремо або імена (їх також називають «ключами»), або значення:

julia> keys(s)
(:name, :grade)

julia> values(s)
("Helen", 3)

Зауважмо, що під час ітерації іменованим кортежем отримуємо лише значення, а імена ігноруються.

Якщо імена теж потрібні під час ітерації, знадобиться більше кроків. NamedTuple можна перетворити на Vector із Pairs (Pair - тема іншої концепції).

julia> pairs(s)
pairs(::NamedTuple) with 2 entries:
  :name  => "Helen"
  :grade => 3

julia> collect(pairs(s))
2-element Vector{Pair{Symbol, Any}}:
  :name => "Helen"
  :grade => 3

Отже, іменований кортеж досить схожий на словник. Однак він відрізняється від [Dict][dict] у Julia кількома важливими рисами:

  • Dict змінний; NamedTuple, як і будь-який кортеж, незмінний.
  • Dict гнучкий щодо типу ключів, які приймає; NamedTuple може використовувати як ключі лише символи.

Кортежі (іменовані чи ні) дуже часто використовують для передавання структурованих даних у функції та з них. Незмінність у цьому випадку корисна: вона забезпечує безпеку даних і дає компілятору змогу застосовувати агресивніші оптимізації.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Кортежі