如何从 Julia 列表中删除元素?

Dil*_*ila 8 julia

v = range(1e10, -1e10, step=-1e8) # velocities [cm/s]
deleteat!(v, findall(x->x==0,v))
Run Code Online (Sandbox Code Playgroud)

我想0从 中删除该值v。按照本教程,我尝试了deleteat!但收到错误

MethodError: no method matching deleteat!(::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, ::Vector{Int64})
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?

Prz*_*fel 7

使用filter!filter


julia> filter!(!=(0), [1,0,2,0,4])
3-element Vector{Int64}:
 1
 2
 4
Run Code Online (Sandbox Code Playgroud)

如果是,range您可以collect使用或使用:

julia> filter(!=(0), range(2, -2, step=-1))
4-element Vector{Int64}:
  2
  1
 -1
 -2
Run Code Online (Sandbox Code Playgroud)

然而,对于大范围,您可能不想将它们具体化以节省内存占用。在这种情况下你可以使用:

(x for x in range(2, -2, step=-1) if x !== 0)
Run Code Online (Sandbox Code Playgroud)

要查看正在生成的内容,您需要collect

julia> collect(x for x in range(2, -2, step=-1) if x !== 0)
4-element Vector{Int64}:
  2
  1
 -1
 -2
Run Code Online (Sandbox Code Playgroud)

  • @Dila 使用 `filter` (不带 `!`):`v = filter(!=(0), range(1e10, -1e10, step=-1e8)) `。与收集然后删除方法相比,此方法的优点是这里直接形成 Vector,没有不需要的元素(在本例中为“0”)。当你“收集”然后“删除!”时,必须形成完整的向量,然后进行删除,并且“0”右侧的元素(即其中的一半)都需要向左移动以填充差距。使用“过滤器”可以避免昂贵的两步过程。 (2认同)

Dav*_*olz 4

请注意该函数返回的类型range

typeof(range(1e10, -1e10, step=-1e8))
Run Code Online (Sandbox Code Playgroud)

上面的结果是

StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}
Run Code Online (Sandbox Code Playgroud)

调用该函数的帮助函数deleteat!

? deleteat!()
Run Code Online (Sandbox Code Playgroud)

deleteat!(a::Vector, inds)

删除 inds 给出的索引处的项目,并返回 > 修改后的 a。后续项目将被转移以填补由此产生的空白。

inds 可以是迭代器,也可以是排序且>唯一整数索引的集合,也可以是与 a 长度相同的布尔向量,其中 true 指示要删除的条目。

range我们可以使用来转换返回的类型collect。尝试以下代码。

v = collect(range(1e10, -1e10, step=-1e8))
deleteat!(v,findall(x->x==0,v))
Run Code Online (Sandbox Code Playgroud)

请注意,我们可以缩短x->x==0iszero

v = collect(range(1e10, -1e10, step=-1e8))
deleteat!(v,findall(iszero,v))
Run Code Online (Sandbox Code Playgroud)