Iteration utilities
Base.Iterators.Stateful
— TypeStateful(itr)
Существует несколько различных способов рассмотреть эту обертку итератора:
- Она предоставляет изменяемую обертку вокруг итератора и его состояния итерации.
- Она превращает абстракцию, похожую на итератор, в абстракцию, похожую на
Channel
. - Это итератор, который изменяется, чтобы стать своим собственным итератором остатка, когда элемент производится.
Stateful
предоставляет обычный интерфейс итератора. Как и другие изменяемые итераторы (например, Base.Channel
), если итерация прерывается преждевременно (например, с помощью break
в цикле for
), итерация может быть возобновлена с того же места, продолжая итерацию по тому же объекту итератора (в отличие от неизменяемого итератора, который бы начал с самого начала).
Примеры
julia> a = Iterators.Stateful("abcdef");
julia> isempty(a)
false
julia> popfirst!(a)
'a': ASCII/Unicode U+0061 (категория Ll: буква, строчная)
julia> collect(Iterators.take(a, 3))
3-element Vector{Char}:
'b': ASCII/Unicode U+0062 (категория Ll: буква, строчная)
'c': ASCII/Unicode U+0063 (категория Ll: буква, строчная)
'd': ASCII/Unicode U+0064 (категория Ll: буква, строчная)
julia> collect(a)
2-element Vector{Char}:
'e': ASCII/Unicode U+0065 (категория Ll: буква, строчная)
'f': ASCII/Unicode U+0066 (категория Ll: буква, строчная)
julia> Iterators.reset!(a); popfirst!(a)
'a': ASCII/Unicode U+0061 (категория Ll: буква, строчная)
julia> Iterators.reset!(a, "hello"); popfirst!(a)
'h': ASCII/Unicode U+0068 (категория Ll: буква, строчная)
julia> a = Iterators.Stateful([1,1,1,2,3,4]);
julia> for x in a; x == 1 || break; end
julia> peek(a)
3
julia> sum(a) # Сумма оставшихся элементов
7
Base.Iterators.zip
— Functionzip(iters...)
Запускает несколько итераторов одновременно, пока один из них не исчерпается. Тип значения итератора zip
— это кортеж значений его подитераторов.
zip
упорядочивает вызовы своих подитераторов таким образом, что состояния итераторов не будут продвигаться, когда другой итератор завершает работу в текущей итерации.
zip()
без аргументов возвращает бесконечный итератор пустых кортежей.
См. также: enumerate
, Base.splat
.
Примеры
julia> a = 1:5
1:5
julia> b = ["e","d","b","c","a"]
5-element Vector{String}:
"e"
"d"
"b"
"c"
"a"
julia> c = zip(a,b)
zip(1:5, ["e", "d", "b", "c", "a"])
julia> length(c)
5
julia> first(c)
(1, "e")
Base.Iterators.enumerate
— Functionenumerate(iter)
Итератор, который возвращает (i, x)
, где i
— это счетчик, начинающийся с 1, а x
— это i
-е значение из данного итератора. Это полезно, когда вам нужны не только значения x
, по которым вы итерируете, но и количество итераций на данный момент.
Обратите внимание, что i
может быть недействительным для индексации iter
или может индексировать другой элемент. Это произойдет, если iter
имеет индексы, которые не начинаются с 1, и может произойти для строк, словарей и т. д. См. метод pairs(IndexLinear(), iter)
, если вы хотите убедиться, что i
является индексом.
Примеры
julia> a = ["a", "b", "c"];
julia> for (index, value) in enumerate(a)
println("$index $value")
end
1 a
2 b
3 c
julia> str = "naïve";
julia> for (i, val) in enumerate(str)
print("i = ", i, ", val = ", val, ", ")
try @show(str[i]) catch e println(e) end
end
i = 1, val = n, str[i] = 'n'
i = 2, val = a, str[i] = 'a'
i = 3, val = ï, str[i] = 'ï'
i = 4, val = v, StringIndexError("naïve", 4)
i = 5, val = e, str[i] = 'v'
Base.Iterators.rest
— Functionrest(iter, state)
Итератор, который возвращает те же элементы, что и iter
, но начиная с указанного state
.
См. также: Iterators.drop
, Iterators.peel
, Base.rest
.
Примеры
julia> collect(Iterators.rest([1,2,3,4], 2))
3-element Vector{Int64}:
2
3
4
Base.Iterators.countfrom
— Functioncountfrom(start=1, step=1)
Итератор, который считает бесконечно, начиная с start
и увеличивая на step
.
Примеры
julia> for v in Iterators.countfrom(5, 2)
v > 10 && break
println(v)
end
5
7
9
Base.Iterators.take
— Functiontake(iter, n)
Итератор, который генерирует не более первых n
элементов iter
.
См. также: drop
, peel
, first
, Base.take!
.
Примеры
julia> a = 1:2:11
1:2:11
julia> collect(a)
6-element Vector{Int64}:
1
3
5
7
9
11
julia> collect(Iterators.take(a,3))
3-element Vector{Int64}:
1
3
5
Base.Iterators.takewhile
— Functiontakewhile(pred, iter)
Итератор, который генерирует элементы из iter
, пока предикат pred
истинный, после чего отбрасывает все элементы.
Эта функция требует как минимум Julia 1.4.
Примеры
julia> s = collect(1:5)
5-element Vector{Int64}:
1
2
3
4
5
julia> collect(Iterators.takewhile(<(3),s))
2-element Vector{Int64}:
1
2
Base.Iterators.drop
— Functiondrop(iter, n)
Итератор, который генерирует все элементы iter
, кроме первых n
.
Примеры
julia> a = 1:2:11
1:2:11
julia> collect(a)
6-element Vector{Int64}:
1
3
5
7
9
11
julia> collect(Iterators.drop(a,4))
2-element Vector{Int64}:
9
11
Base.Iterators.dropwhile
— Functiondropwhile(pred, iter)
Итератор, который отбрасывает элементы из iter
, пока предикат pred
истинен, после чего возвращает каждый элемент.
Эта функция требует как минимум Julia 1.4.
Примеры
julia> s = collect(1:5)
5-element Vector{Int64}:
1
2
3
4
5
julia> collect(Iterators.dropwhile(<(3),s))
3-element Vector{Int64}:
3
4
5
Base.Iterators.cycle
— Functioncycle(iter[, n::Int])
Итератор, который бесконечно проходит по iter
. Если указано n
, то он проходит по iter
столько раз. Когда iter
пуст, то и cycle(iter)
, и cycle(iter, n)
тоже пусты.
Iterators.cycle(iter, n)
является ленивым эквивалентом Base.repeat
(vector, n)
, в то время как Iterators.repeated
(iter, n)
является ленивым Base.fill
(item, n)
.
Метод cycle(iter, n)
был добавлен в Julia 1.11.
Примеры
julia> for (i, v) in enumerate(Iterators.cycle("hello"))
print(v)
i > 10 && break
end
hellohelloh
julia> foreach(print, Iterators.cycle(['j', 'u', 'l', 'i', 'a'], 3))
juliajuliajulia
julia> repeat([1,2,3], 4) == collect(Iterators.cycle([1,2,3], 4))
true
julia> fill([1,2,3], 4) == collect(Iterators.repeated([1,2,3], 4))
true
Base.Iterators.repeated
— Functionrepeated(x[, n::Int])
Итератор, который генерирует значение x
бесконечно. Если n
указано, генерирует x
столько раз (эквивалентно take(repeated(x), n)
).
См. также fill
и сравните с Iterators.cycle
.
Примеры
julia> a = Iterators.repeated([1 2], 4);
julia> collect(a)
4-element Vector{Matrix{Int64}}:
[1 2]
[1 2]
[1 2]
[1 2]
julia> ans == fill([1 2], 4)
true
julia> Iterators.cycle([1 2], 4) |> collect |> println
[1, 2, 1, 2, 1, 2, 1, 2]
Base.Iterators.product
— Functionproduct(iters...)
Возвращает итератор по произведению нескольких итераторов. Каждый сгенерированный элемент является кортежем, чей i
-й элемент берется из i
-го аргумента-итератора. Первый итератор изменяется быстрее всего.
Смотрите также: zip
, Iterators.flatten
.
Примеры
julia> collect(Iterators.product(1:2, 3:5))
2×3 Matrix{Tuple{Int64, Int64}}:
(1, 3) (1, 4) (1, 5)
(2, 3) (2, 4) (2, 5)
julia> ans == [(x,y) for x in 1:2, y in 3:5] # собирает генератор, использующий Iterators.product
true
Base.Iterators.flatten
— Functionflatten(iter)
Данный итератор, который возвращает итераторы, возвращает итератор, который выдает элементы этих итераторов. Иными словами, элементы аргументированного итератора конкатенируются.
Примеры
julia> collect(Iterators.flatten((1:2, 8:9)))
4-element Vector{Int64}:
1
2
8
9
julia> [(x,y) for x in 0:1 for y in 'a':'c'] # собирает генераторы, использующие Iterators.flatten
6-element Vector{Tuple{Int64, Char}}:
(0, 'a')
(0, 'b')
(0, 'c')
(1, 'a')
(1, 'b')
(1, 'c')
Base.Iterators.flatmap
— FunctionIterators.flatmap(f, iterators...)
Эквивалентно flatten(map(f, iterators...))
.
См. также Iterators.flatten
, Iterators.map
.
Эта функция была добавлена в Julia 1.9.
Примеры
julia> Iterators.flatmap(n -> -n:2:n, 1:3) |> collect
9-element Vector{Int64}:
-1
1
-2
0
2
-3
-1
1
3
julia> stack(n -> -n:2:n, 1:3)
ERROR: DimensionMismatch: stack expects uniform slices, got axes(x) == (1:3,) while first had (1:2,)
[...]
julia> Iterators.flatmap(n -> (-n, 10n), 1:2) |> collect
4-element Vector{Int64}:
-1
10
-2
20
julia> ans == vec(stack(n -> (-n, 10n), 1:2))
true
Base.Iterators.partition
— Functionpartition(collection, n)
Итерация по коллекции n
элементов за раз.
Примеры
julia> collect(Iterators.partition([1,2,3,4,5], 2))
3-element Vector{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}:
[1, 2]
[3, 4]
[5]
Base.Iterators.map
— FunctionIterators.map(f, iterators...)
Создает ленивое отображение. Это другой синтаксис для записи (f(args...) for args in zip(iterators...))
.
Эта функция требует как минимум Julia 1.6.
Примеры
julia> collect(Iterators.map(x -> x^2, 1:3))
3-element Vector{Int64}:
1
4
9
Base.Iterators.filter
— FunctionIterators.filter(flt, itr)
Данная функция принимает предикат flt
и итерируемый объект itr
, возвращая итерируемый объект, который при итерации выдает элементы x
из itr
, удовлетворяющие условию flt(x)
. Порядок оригинального итератора сохраняется.
Эта функция ленивая; то есть, она гарантированно возвращает результат за $Θ(1)$ время и использует $Θ(1)$ дополнительного пространства, а flt
не будет вызвана при вызове filter
. Вызовы к flt
будут производиться при итерации по возвращаемому итерируемому объекту. Эти вызовы не кэшируются, и повторные вызовы будут производиться при повторной итерации.
Последующие ленивые преобразования итератора, возвращаемого из filter
, такие как те, что выполняются с помощью Iterators.reverse
или cycle
, также отложат вызовы к flt
до тех пор, пока не будет выполнено сбор или итерация по возвращаемому итерируемому объекту. Если предикат фильтра является недетерминированным или его возвращаемые значения зависят от порядка итерации по элементам itr
, композиция с ленивыми преобразованиями может привести к неожиданному поведению. Если это нежелательно, либо убедитесь, что flt
является чистой функцией, либо соберите промежуточные итераторы filter
перед дальнейшими преобразованиями.
Смотрите Base.filter
для жадной реализации фильтрации для массивов.
Примеры
julia> f = Iterators.filter(isodd, [1, 2, 3, 4, 5])
Base.Iterators.Filter{typeof(isodd), Vector{Int64}}(isodd, [1, 2, 3, 4, 5])
julia> foreach(println, f)
1
3
5
julia> [x for x in [1, 2, 3, 4, 5] if isodd(x)] # собирает генератор по Iterators.filter
3-element Vector{Int64}:
1
3
5
Base.Iterators.accumulate
— FunctionIterators.accumulate(f, itr; [init])
Данная функция принимает функцию с 2 аргументами f
и итератор itr
, возвращает новый итератор, который последовательно применяет f
к предыдущему значению и следующему элементу itr
.
Это фактически ленивый вариант Base.accumulate
.
Ключевой аргумент init
добавлен в Julia 1.5.
Примеры
julia> a = Iterators.accumulate(+, [1,2,3,4]);
julia> foreach(println, a)
1
3
6
10
julia> b = Iterators.accumulate(/, (2, 5, 2, 5); init = 100);
julia> collect(b)
4-element Vector{Float64}:
50.0
10.0
5.0
1.0
Base.Iterators.reverse
— FunctionIterators.reverse(itr)
Данный итератор itr
, тогда reverse(itr)
является итератором по той же коллекции, но в обратном порядке. Этот итератор "ленивый" в том смысле, что он не создает копию коллекции для ее реверсирования; см. Base.reverse
для жадной реализации.
(По умолчанию это возвращает объект Iterators.Reverse
, оборачивающий itr
, который можно перебирать, если соответствующие методы iterate
определены, но некоторые типы itr
могут реализовывать более специализированные поведения Iterators.reverse
.)
Не все типы итераторов T
поддерживают итерацию в обратном порядке. Если T
этого не поддерживает, то перебор Iterators.reverse(itr::T)
вызовет MethodError
из-за отсутствующих методов iterate
для Iterators.Reverse{T}
. (Чтобы реализовать эти методы, оригинальный итератор itr::T
можно получить из объекта r::Iterators.Reverse{T}
с помощью r.itr
; более общим образом, можно использовать Iterators.reverse(r)
.)
Примеры
julia> foreach(println, Iterators.reverse(1:5))
5
4
3
2
1
Base.Iterators.only
— Functiononly(x)
Возвращает единственный элемент коллекции x
или выбрасывает ArgumentError
, если коллекция содержит ноль или несколько элементов.
Этот метод требует как минимум Julia 1.4.
Примеры
julia> only(["a"])
"a"
julia> only("a")
'a': ASCII/Unicode U+0061 (категория Ll: буква, строчная)
julia> only(())
ERROR: ArgumentError: Кортеж содержит 0 элементов, должен содержать ровно 1 элемент
Stacktrace:
[...]
julia> only(('a', 'b'))
ERROR: ArgumentError: Кортеж содержит 2 элемента, должен содержать ровно 1 элемент
Stacktrace:
[...]
Base.Iterators.peel
— Functionpeel(iter)
Возвращает первый элемент и итератор по оставшимся элементам.
Если итератор пуст, возвращает nothing
(как iterate
).
Предыдущие версии выбрасывают BoundsError, если итератор пуст.
См. также: Iterators.drop
, Iterators.take
.
Примеры
julia> (a, rest) = Iterators.peel("abc");
julia> a
'a': ASCII/Unicode U+0061 (категория Ll: Буква, строчная)
julia> collect(rest)
2-element Vector{Char}:
'b': ASCII/Unicode U+0062 (категория Ll: Буква, строчная)
'c': ASCII/Unicode U+0063 (категория Ll: Буква, строчная)