列出朱莉娅的理解和元组

时间:2016-03-31 15:44:48

标签: julia

我正在尝试在Julia中执行此Python代码的功能。 (查找组合值大于7的两个列表中的所有对。)

#Python    
def sum_is_large(a, b):
    return a + b > 7

l1 = [1,2,3]
l2 = [4,5,6]
l3 = [(a,b) for a in l1 for b in l2 if sum_is_large(a, b)]
print(l3)

朱莉娅的列表理解没有“如果”。如果我使用filter(),我不确定我是否可以传递两个参数。所以我最好的建议是:

#Julia
function sum_is_large(pair)
    a, b = pair
    return a + b > 7 
end

l1 = [1,2,3]
l2 = [4,5,6]

l3 = filter(sum_is_large, [(i,j) for i in l1, j in l2])
print(l3)

我觉得这不太吸引人。所以我的问题是,朱莉娅有更好的方法吗?

6 个答案:

答案 0 :(得分:6)

在Julia中使用非常受欢迎的包Iterators.jl:

using Iterators       # install using Pkg.add("Iterators")
filter(x->sum(x)>7,product(l1,l2))

是生成对的迭代器。所以要获得与OP相同的打印输出:

l3iter = filter(x->sum(x)>7,product(l1,l2))
for p in l3iter println(p); end

迭代器方法可能具有更高的内存效率。当然,人们可以l3 = collect(l3iter)得到对矢量。

@ user2317519,好奇,是否有一个等效的python迭代器形式?

答案 1 :(得分:3)

Guard(if)现已在Julia v0.5中提供(目前处于候选发布阶段):

julia> v1 = [1, 2, 3];

julia> v2 = [4, 5, 6];

julia> v3 = [(a, b) for a in v1, b in v2 if a+b > 7]
3-element Array{Tuple{Int64,Int64},1}:
 (3,5)
 (2,6)
 (3,6)

请注意,现在还可以使用生成器:

julia> g = ( (a, b) for a in v1, b in v2 if a+b > 7 )
Base.Generator{Filter{##18#20,Base.Prod2{Array{Int64,1},Array{Int64,1}}},##17#19}(#17,Filter{##18#20,Base.Prod2{Array{Int64,1},Array{Int64,1}}}(#18,Base.Prod2{Array{Int64,1},Array{Int64,1}}([1,2,3],[4,5,6])))

答案 2 :(得分:2)

另一个类似于@DanGetz的选项也使用Iterators.jl

function expensive_fun(a, b)
    return (a + b)
end

然后,如果条件也很复杂,可以将其定义为函数:

condition(x) = x > 7

最后,过滤结果:

>>> using Iterators
>>> result = filter(condition, imap(expensive_fun, l1, l2))

result是一个可迭代的,仅在需要时(便宜)计算,如果需要可以收集collect(result)

如果过滤条件足够简单,那么单行将是:

>>> result = filter(x->(x > 7), imap(expensive_fun, l1, l2))

注意:imap本身适用于任意数量的参数。

答案 3 :(得分:1)

也许是这样的:

500 Internal Server Error

虽然我同意它看起来不应该是最好的方式......

答案 4 :(得分:0)

我很惊讶没有人提到三元运算符来实现条件:

julia> l3 = [sum_is_large((i,j)) ? (i,j) : nothing for i in l1, j in l2]
3x3 Array{Tuple,2}:
 nothing  nothing  nothing
 nothing  nothing  (2,6)  
 nothing  (3,5)    (3,6)

或甚至只是复合语句中的正常if块,即

[ (if sum_is_large((x,y)); (x,y); end) for x in l1, y in l2 ]

给出相同的结果。

我觉得这个结果比filter()更有意义,因为在julia中a in A, b in B结构被解释为维度,因此输出实际上是“阵列理解”具有适当的维度,在许多情况下显然是有利的,并且可能是期望的行为(无论我们是否包括有条件的)。

而过滤器将始终返回向量。显然,如果你真的想要一个矢量结果,你总是可以collect结果;或者像这里的条件列表理解一样,您可以通过执行nothing从数组中删除l3 = l3[l3 .!= nothing]个元素。

据推测,这仍然比filter()方法更清晰,效率更低。

答案 5 :(得分:0)

您可以使用VectorizedRoutines.jl中的@vcomp(矢量理解)宏来执行类似Python的理解:

using VectorizedRoutines
Python.@vcomp Int[i^2 for i in 1:10] when i % 2 == 0 # Int[4, 16, 36, 64, 100]