迭代实用程序
Base.Iterators.Stateful — 类型Stateful(itr)有几种不同的方法可以考虑这个迭代器包装器
- 它提供了一个可变的包装器,用于包装迭代器及其迭代状态。
- 它将类似迭代器的抽象转换为类似
Channel的抽象。 - 它是一个迭代器,它会变异为自己的剩余迭代器,只要产生一个项目。
Stateful 提供了常规的迭代器接口。与其他可变迭代器(例如 Base.Channel)一样,如果迭代过早停止(例如,在 for 循环中通过 break),可以通过继续迭代同一个迭代器对象来从同一位置恢复迭代(相比之下,不可变迭代器将从头开始)。
示例
julia> a = Iterators.Stateful("abcdef");
julia> isempty(a)
false
julia> popfirst!(a)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
julia> collect(Iterators.take(a, 3))
3-element Vector{Char}:
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
julia> collect(a)
2-element Vector{Char}:
'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)
'f': ASCII/Unicode U+0066 (category Ll: Letter, lowercase)
julia> Iterators.reset!(a); popfirst!(a)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
julia> Iterators.reset!(a, "hello"); popfirst!(a)
'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)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) # Sum the remaining elements
7Base.Iterators.zip — 函数zip(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 — 函数enumerate(iter)一个迭代器,它会生成(i, x),其中i 是从 1 开始的计数器,x 是给定迭代器的第i 个值。当您不仅需要迭代的值x,还需要到目前为止的迭代次数时,它很有用。
请注意,i 可能不是索引iter 的有效值,或者可能索引不同的元素。如果iter 的索引不是从 1 开始,就会发生这种情况,并且可能会发生在字符串、字典等中。如果您想确保i 是一个索引,请参见pairs(IndexLinear(), iter) 方法。
示例
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 — 函数rest(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
4Base.Iterators.countfrom — 函数countfrom(start=1, step=1)一个永远计数的迭代器,从start 开始,以step 为增量。
示例
julia> for v in Iterators.countfrom(5, 2)
v > 10 && break
println(v)
end
5
7
9Base.Iterators.take — 函数take(iter, n)一个迭代器,它最多会生成iter 的前n 个元素。
另见: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
5Base.Iterators.takewhile — 函数takewhile(pred, iter)一个迭代器,只要谓词pred 为真,就会生成iter 中的元素,之后,会丢弃所有元素。
此函数至少需要 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
2Base.Iterators.drop — 函数drop(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
11Base.Iterators.dropwhile — 函数dropwhile(pred, iter)一个迭代器,只要谓词pred 为真,就会丢弃iter 中的元素,之后,会返回所有元素。
此函数至少需要 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
5Base.Iterators.cycle — 函数cycle(iter)一个无限循环遍历iter 的迭代器。如果iter 为空,则cycle(iter) 也是空的。
另见:Iterators.repeated,Base.repeat。
示例
julia> for (i, v) in enumerate(Iterators.cycle("hello"))
print(v)
i > 10 && break
end
hellohellohBase.Iterators.repeated — 函数repeated(x[, n::Int])一个迭代器,它会无限期地生成值x。如果指定了n,则会生成x 这么多次(等效于take(repeated(x), n))。
另见:Iterators.cycle,Base.repeat。
示例
julia> a = Iterators.repeated([1 2], 4);
julia> collect(a)
4-element Vector{Matrix{Int64}}:
[1 2]
[1 2]
[1 2]
[1 2]Base.Iterators.product — 函数product(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] # collects a generator involving Iterators.product
trueBase.Iterators.flatten — 函数flatten(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'] # collects generators involving Iterators.flatten
6-element Vector{Tuple{Int64, Char}}:
(0, 'a')
(0, 'b')
(0, 'c')
(1, 'a')
(1, 'b')
(1, 'c')Base.Iterators.flatmap — 函数Iterators.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))
trueBase.Iterators.partition — 函数partition(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 — 函数Iterators.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
9Base.Iterators.filter — 函数Iterators.filter(flt, itr)给定一个谓词函数flt 和一个可迭代对象itr,返回一个可迭代对象,该对象在迭代时会生成满足flt(x) 的itr 的元素x。原始迭代器的顺序保持不变。
此函数是延迟的;也就是说,它保证在$Θ(1)$ 时间内返回,并使用$Θ(1)$ 个额外的空间,并且不会通过filter 的调用来调用flt。当迭代返回的可迭代对象时,会调用flt。这些调用不会被缓存,并且在重新迭代时会进行重复调用。
有关数组过滤的急切实现,请参见 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)] # collects a generator over Iterators.filter
3-element Vector{Int64}:
1
3
5Base.Iterators.accumulate — 函数Iterators.accumulate(f, itr; [init])给定一个 2 个参数的函数f 和一个迭代器itr,返回一个新的迭代器,该迭代器会依次将f 应用于前一个值和itr 的下一个元素。
这实际上是 Base.accumulate 的延迟版本。
Julia 1.5 版本中添加了关键字参数 init。
示例
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.0Base.Iterators.reverse — 函数Iterators.reverse(itr)给定一个迭代器 itr,则 reverse(itr) 是一个对相同集合进行反向迭代的迭代器。这个迭代器是“惰性的”,因为它不会为了反转而复制集合;参见 Base.reverse 获取一个积极的实现。
(默认情况下,这将返回一个包装 itr 的 Iterators.Reverse 对象,如果相应的 iterate 方法已定义,则该对象是可迭代的,但一些 itr 类型可能会实现更专业的 Iterators.reverse 行为。)
并非所有迭代器类型 T 都支持反向迭代。如果 T 不支持,则迭代 Iterators.reverse(itr::T) 将抛出一个 MethodError,因为 Iterators.Reverse{T} 缺少 iterate 方法。(为了实现这些方法,原始迭代器 itr::T 可以从 r::Iterators.Reverse{T} 对象中通过 r.itr 获取;更一般地,可以使用 Iterators.reverse(r)。)
示例
julia> foreach(println, Iterators.reverse(1:5))
5
4
3
2
1Base.Iterators.only — 函数only(x)返回集合 x 中唯一的元素,如果集合中包含零个或多个元素,则抛出一个 ArgumentError。
此方法需要至少 Julia 1.4 版本。
示例
julia> only(["a"])
"a"
julia> only("a")
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
julia> only(())
ERROR: ArgumentError: Tuple contains 0 elements, must contain exactly 1 element
Stacktrace:
[...]
julia> only(('a', 'b'))
ERROR: ArgumentError: Tuple contains 2 elements, must contain exactly 1 element
Stacktrace:
[...]Base.Iterators.peel — 函数peel(iter)返回第一个元素和一个对剩余元素进行迭代的迭代器。
如果迭代器为空,则返回 nothing(类似于 iterate)。
早期版本如果迭代器为空,则抛出 BoundsError。
另见:Iterators.drop、Iterators.take。
示例
julia> (a, rest) = Iterators.peel("abc");
julia> a
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
julia> collect(rest)
2-element Vector{Char}:
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)