趋近智
while 循环进行条件迭代break 和 continueprint 和 println 显示输出@printf格式化输出try-catch 进行异常处理finally 保证代码执行你已经了解了如何逐个构建数组和字典等集合,或者使用函数来生成它们。现在,我们来看一种强大且简洁的集合创建方法:推导式。推导式提供了一种紧凑的语法,可以从现有可迭代对象(如范围或其他集合)生成集合,这通常使你的代码更具可读性和表现力,尤其是在创建新集合的逻辑直接明了时。
可以把推导式看作是一种常见模式的简写:对一些值进行迭代,对每个值执行操作,然后将结果收集到一个新集合中。
数组推导式可能是你最常遇到的类型。它们允许你在一行可读的代码中,根据一个表达式和一个输入序列来定义数组的内容。
数组推导式的基本语法是:
[expression for variable in iterable]
让我们分解一下:
expression:这是新数组中每个元素将计算的值。它通常会用到 variable。variable:这是一个占位符,它会逐一取用 iterable 中每个项的值。iterable:这是任何可以被循环的对象,例如一个范围(1:5)、一个现有数组或一个字符串。[] 表示正在创建一个 Array。例如,如果我们想创建一个包含前五个正整数平方的数组,与其编写循环并使用 push! 将元素添加到数组中,不如使用推导式:
julia> squares = [i*i for i in 1:5]
5-element Vector{Int64}:
1
4
9
16
25
在这里,i 取值从 1 到 5,i*i 被计算,结果成为 squares 数组中的一个元素。
if 进行筛选推导式还可以包含 if 子句,以便在应用表达式之前从可迭代对象中筛选项。语法变为:
[expression for variable in iterable if condition]
只有 condition 评估为 true 的项才会被 expression 处理并包含在结果数组中。
假设我们想要一个平方数组,但只包含 1 到 10 之间的偶数:
julia> even_squares = [x^2 for x in 1:10 if x % 2 == 0]
5-element Vector{Int64}:
4
16
36
64
100
在这个例子中,x 从 1 迭代到 10。if x % 2 == 0 条件检查 x 是否为偶数。如果是,则计算 x^2 并将其添加到 even_squares 数组中。
如果 Julia 的自动类型推断不是你所需要的,你也可以指定结果数组的元素类型:
julia> float_halves = Float64[i/2 for i in 1:5]
5-element Vector{Float64}:
0.5
1.0
1.5
2.0
2.5
这确保了 float_halves 是一个 Float64 值的数组。
与数组推导式类似,字典推导式提供了一种简洁的创建字典的方法。语法包括为可迭代对象中的每个项指定一个键值对。
一般形式是:
Dict(key_expression => value_expression for variable in iterable)
或者带条件时:
Dict(key_expression => value_expression for variable in iterable if condition)
让我们创建一个字典,它的键是 1 到 5 的数字,值是它们的立方:
julia> number_to_cube = Dict(i => i^3 for i in 1:5)
Dict{Int64, Int64} with 5 entries:
5 => 125
4 => 64
2 => 8
3 => 27
1 => 1
在这里,对于从 1 到 5 的每个 i,都会创建一个 i => i^3 对并添加到字典中。
你也可以通过使用 zip 同时迭代多个集合来创建字典,zip 会将两个或更多可迭代对象中对应的元素配对。
julia> names = ["Alice", "Bob", "Charlie"];
julia> ages = [30, 24, 35];
julia> name_to_age = Dict(name => age for (name, age) in zip(names, ages))
Dict{String, Int64} with 3 entries:
"Bob" => 24
"Alice" => 30
"Charlie" => 35
在这种情况下,(name, age) 是一个元组,它从 zip(names, ages) 生成的每对中解包出来。
如果你不想立即创建一个完整的数组或字典,而是想要一个可以按需生成值的对象,该怎么办?这就是生成器表达式的作用。它们看起来与数组推导式非常相似,但没有外部的方括号。
语法是:
(expression for variable in iterable if condition)
这会创建一个 生成器。生成器是可迭代对象。它不会一次性计算所有值并存储在内存中。相反,它会按需逐个计算值。对于大型序列,这可以非常节省内存。
julia> gen = (i * 10 for i in 1:5)
Base.Generator{UnitRange{Int64}, var"#5#6"}(var"#5#6"(), 1:5)
julia> for val in gen
println(val)
end
10
20
30
40
50
注意,打印 gen 本身并不会显示值,而是显示一个代表生成器的对象。值是在你迭代它时生成的。
这些生成器表达式特别有用,因为它们可以传递给集合构造函数来构建元组 (Tuples)、集合 (Sets),甚至数组和字典(如果你喜欢这种两步法,尽管直接推导式对于数组和字典通常更符合习惯)。
要使用类似推导式的语法创建元组,你可以在 Tuple 构造函数中使用生成器表达式:
julia> odd_numbers_tuple = Tuple(x for x in 1:10 if x % 2 != 0)
(1, 3, 5, 7, 9)
同样,对于存储唯一项的集合:
julia> unique_chars = Set(c for c in "hello world!" if isletter(c))
Set{Char} with 10 entries:
'r'
'e'
'h'
'w'
'l'
'o'
'd'
即使 'l' 和 'o' 在 "hello world!" 中多次出现,它们在集合中也只出现一次,并且由于 if isletter(c) 条件,只有字母被包含在内。
推导式和生成器表达式是 Julia 中富有表现力的代码的标志。它们让你能清楚地表达 要构建什么(你想构建的集合),而不是 如何构建(显式的循环和追加机制),从而在你熟悉它们的结构后,编写出更简洁、通常也更易读的代码。它们在 Julia 程序中很常见,所以理解它们对于编写自己的代码和阅读他人的代码都非常重要。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造