我正在尝试在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)
我觉得这不太吸引人。所以我的问题是,朱莉娅有更好的方法吗?
答案 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]