13

在 python 中,我可以进行嵌套列表推导,例如,我可以展平以下数组:

a = [[1,2,3],[4,5,6]]
[i for arr in a for i in arr]

要得到[1,2,3,4,5,6]

如果我在 Julia 中尝试这种语法,我会得到:

julia> a
([1,2,3],[4,5,6],[7,8,9])

julia> [i for arr in a for i in arr]
ERROR: syntax: expected ]

Julia 中的嵌套列表推导可能吗?

4

5 回答 5

21

此功能已在 julia v0.5 中添加:

julia> a = ([1,2,3],[4,5,6],[7,8,9])
([1,2,3],[4,5,6],[7,8,9])

julia> [i for arr in a for i in arr]
9-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
 7
 8
 9
于 2016-08-25T19:36:57.050 回答
15

列表推导在 Julia 中的工作方式略有不同:

> [(x,y) for x=1:2, y=3:4]
2x2 Array{(Int64,Int64),2}:
 (1,3)  (1,4)
 (2,3)  (2,4)

如果a=[[1 2],[3 4],[5 6]]是多维数组,vec会将其展平:

> vec(a)
6-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6

由于 a 包含元组,这在 Julia 中有点复杂。这可行,但可能不是处理它的最佳方法:

function flatten(x, y)
    state = start(x)
    if state==false
        push!(y, x)
    else
        while !done(x, state) 
          (item, state) = next(x, state) 
          flatten(item, y)
        end 
    end
    y
end
flatten(x)=flatten(x,Array(Any, 0))

然后,我们可以运行:

> flatten([(1,2),(3,4)])
4-element Array{Any,1}:
 1
 2
 3
 4
于 2014-01-15T05:52:16.060 回答
6

您可以在此处使用带有数组构造函数的splat 运算符获得一些好处(转置以节省空间)

julia> a = ([1,2,3],[4,5,6],[7,8,9])
([1,2,3],[4,5,6],[7,8,9])

julia> [a...]'
1x9 Array{Int64,2}:
 1  2  3  4  5  6  7  8  9
于 2015-03-17T03:08:11.457 回答
1

你有什么理由使用向量元组?正如 Ben 已经用vec. 但是在任何一种情况下,您也可以非常简单地使用推导:

julia> a = ([1,2,3],[4,5,6],[7,8,9]);
julia> [i for i in hcat(a...)]
9-element Array{Any,1}:
 1
 2
 ⋮

表达式hcat(a...)“splats”你的元组并将其连接成一个数组。但请记住,与 Python 不同,Julia 使用列优先数组语义。您的元组中有三个列向量;那是你的意图吗?(如果它们是行向量——由空格分隔——你可以用它[a...]来进行连接)。数组遍历所有元素,无论其维度如何。

于 2014-01-15T18:30:16.043 回答
1

没有足够的评论声誉,所以发布修改@ben-hammer。感谢 flatten() 的示例,它对我很有帮助。

但如果元组/数组包含字符串,它确实会中断。由于strings是可迭代的,该函数会将它们进一步分解为字符。我必须插入条件来检查ASCIIString以解决该问题。代码如下

    function flatten(x, y)
        state = start(x)
        if state==false
            push!(y, x)
        else
            if typeof(x) <: String
                push!(y, x)
            else 
                while (!done(x, state)) 
                    (item, state) = next(x, state) 
                    flatten(item, y)
                end
            end
        end
        y
    end
    flatten(x)=flatten(x,Array(Any, 0))
于 2015-09-30T08:24:43.450 回答