Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Julia中的列表理解和元组_Julia_List Comprehension - Fatal编程技术网

Julia中的列表理解和元组

Julia中的列表理解和元组,julia,list-comprehension,Julia,List Comprehension,我试图在Julia中实现Python代码的功能。(从组合值大于7的两个列表中查找所有对。) Julia中的列表理解没有if。如果我使用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 i

我试图在Julia中实现Python代码的功能。(从组合值大于7的两个列表中查找所有对。)

Julia中的列表理解没有
if
。如果我使用
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)

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

也许是这样的:

julia> filter(pair -> pair[1] + pair[2] > 7,  [(i, j) for i in l1, j in l2])
3-element Array{Tuple{Any,Any},1}:
 (3,5)
 (2,6)
 (3,6)

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

使用非常流行的包Iterators.jl,在Julia中:

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是否有一个等价的迭代器形式?

另一个类似于@DanGetz的选项,也使用
迭代器。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
是一个iterable,仅在需要时计算(便宜),如果需要,可以收集
collect(result)

如果过滤条件足够简单,则一行为:

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

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

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

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中的
a,b中的b
构造是维度解释的,因此输出实际上是一个具有适当维度的“数组理解”,这在许多情况下显然是有利的,并且可能是期望的行为(无论我们是否包括有条件的)

然而,过滤器将始终返回向量。显然,如果您确实想要向量结果,您可以始终
收集结果;或者对于像这里这样的条件列表理解,您可以通过执行
l3=l3[l3.!=nothing]
从数组中删除
nothing
元素


大概这比
filter()
方法更清晰、效率更高。

您可以使用vectorizedrodorites.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]
Julia v0.5中现在提供了防护装置(
如果
)(当前处于候选发布阶段):

请注意,发电机现在也可用:

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])))

我喜欢迭代器。如果你导入itertools,你可以在python中做类似的事情。但是,我担心我在试图将我的问题归结为一个简单的例子时犯了一个错误。我的主要问题是元组作为参数。我们可以假设函数sum_是_large()是非常复杂的,它需要重复使用a和b变量。有没有一种方法可以传递这两个变量而不做类似于a,b=pair的事情?
a
b
bigfunc
中可以寻址为
x[1]
x[2]
。您也可以执行
x->bigfunc(x…)
然后定义
bigfunc(a,b)
。这种代码迂回应该不会花费太多的效率,如果有的话。@DanGetz在python中基本上包含与julia的
迭代器相似的迭代器。jl
@DanGetz,我想知道你是否可以对David P.Sanders下面的答案发表评论。2021年,使用
迭代器的好处是什么。jl
如果我理解正确的话,ToR在base Julia中可用?@PatrickT当然你是对的。随着Julia的变化,Stackoverflow的答案也会随之变化。David Sanders的答案看起来不错(运行时间应该是相同的,尽管我没有检查)事实上,SO中的许多代码片段都可以被视为测试代码,因此,明智的做法是提供测试通过/失败的机制,并允许在“标记”(代表工作环境)的版本上跟踪测试。如果SO有优秀的NLP机器人或评论员,他们会选择这个想法并投票表决。
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])))