Julia中的嵌套列表推导

时间:2014-01-15 04:27:37

标签: julia

在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中的嵌套列表推导可能吗?

5 个答案:

答案 0 :(得分:12)

此功能已在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

答案 1 :(得分:9)

列表理解在朱莉娅的工作方式略有不同:

> [(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

由于包含元组,这在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

答案 2 :(得分:3)

你可以在这里使用带有数组构造函数的splat operator获得一些里程(转置以节省空间)

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

答案 3 :(得分: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...]进行连接)。无论数据的维数如何,都会遍历所有元素。

答案 4 :(得分:0)

没有足够的评论声誉所以张贴修改@ 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))