英文:
Equivalent for Python's list comprehension
问题
我正在使用Go语言进行编程,但是在其他语言中非常简单的事情在Go中变得非常困难。
我想要实现一个类似于Python中的推导式:
array := []int{}
for _, a := range anotherArray {
if some condition {
array = append(array, a)
}
}
在Go中,可以使用循环和条件语句来实现类似的功能。以上代码展示了如何使用循环和条件语句来筛选出符合条件的元素并添加到新的数组中。
对于你提到的使用函数的情况,可以使用类似的方法来实现。例如:
min := math.MaxInt64
for i := 0; i < n; i++ {
for j := i; j < n; j++ {
result := someFunction(a[i], b[j])
if result < min {
min = result
}
}
}
以上代码展示了如何使用嵌套循环和条件语句来计算最小值。你可以在循环中调用适当的函数,并根据需要更新最小值。
希望这些代码能帮助到你,让你能够在Go中实现类似于Python推导式的功能。
英文:
I am playing with Go but I am having a very hard time doing things that are very simple in other languages.
I'd like to reproduce a Python comprehension:
array = [a for a in anotherArray if (some condition)]
What is an elegant way to do it in Go? I'd really like to simplify my code, especially when using a function on array. For example:
min = min(abs(a[i], b[j]) for i in range(n)
for j in range(i, n))
答案1
得分: 19
有趣的是,Rob Pike刚刚提出(18小时前)了一个名为filter的库,它可以实现你想要的功能:
例如,可以查看Choose()函数的示例:
// Choose接受一个类型为[]T的切片和一个类型为func(T) bool的函数。(如果不满足输入条件,Choose会引发panic。)它返回一个新分配的切片,其中只包含满足函数条件的输入切片的元素。
在这里进行了测试测试:
func TestChoose(t *testing.T) {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
expect := []int{2, 4, 6, 8}
result := Choose(a, isEven)
正如twotwotwo
在评论中指出的那样,这个库的GoDoc中指出:
> 包filter
包含用于通过应用过滤函数来过滤切片的实用函数。
>
> 该包是一个实验,旨在测试在Go中编写此类功能有多容易。它很容易,但是使用for
循环同样容易且更高效。
>
> 您不应该使用此包。
这个警告在文档“Go泛型讨论总结”的“函数式代码”部分中有所体现:
> 这些通常是高阶函数,例如map
、reduce
(fold
)、filter
、zip
等。
>
> 用例:
类型安全的数据转换:map
、fold
、zip
>
> 使用泛型的优点:
一种简洁的表达数据转换的方式。
>
> 使用泛型的缺点:
最快的解决方案需要考虑何时以及以何种顺序应用这些转换,以及每个步骤生成多少数据。
对于初学者来说,阅读起来更困难。
>
> 替代方案:
>
> 使用for
循环和常规语言结构。
2022年第一季度更新:随着Go中泛型的首次集成(例如,参见“教程:开始使用泛型”),现在您可以在Go中使用泛型实现可能的mapreduce。
请参阅tip.playground和github.com/kevwan/mapreduce/v2
项目。
英文:
Interestingly enough, Rob Pike just proposed (18 hours ago) the library filter which does a bit what you want:
// Choose takes a slice of type []T and a function of type func(T) bool. (If
// the input conditions are not satisfied, Choose panics.) It returns a newly
// allocated slice containing only those elements of the input slice that
// satisfy the function.
func TestChoose(t *testing.T) {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
expect := []int{2, 4, 6, 8}
result := Choose(a, isEven)
As twotwotwo
points out in the comments, the GoDoc for this library states:
> Package filter
contains utility functions for filtering slices through the distributed application of a filter function.
>
> The package is an experiment to see how easy it is to write such things in Go. It is easy, but for
loops are just as easy and more efficient.
>
> You should not use this package.
This caveat is reflected in the document "Summary of Go Generics Discussions", section "Functional Code":
> These are the usual higher-order functions such as map
, reduce
(fold
), filter
, zip
etc.
>
> Cases:
typesafe data transformations: map
, fold
, zip
>
> Pros for using generics:
A concise way to express data transformations.
>
> Cons for using generics:
The fastest solution needs to take into account when and in which order to apply those transformations, and how much data is generated at each step.
It is harder to read for beginners.
>
> Alternative solutions:
>
> use for
loops and usual language constructs.
Update Q1 2022: with the first integration of generics in Go (see for instance "Tutorial: Getting started with generics"), you now have a possible mapreduce implementation with generics in Go.
See tip.playground, and the github.com/kevwan/mapreduce/v2
project.
答案2
得分: 4
如果你正在寻找的是 Python 的列表推导式,在 Go 语言中没有类似的语法等价物。
实现这个功能的方法是创建一个函数,接受一个切片和一个函数(用于测试条件),并返回一个新的切片。
编辑:
看起来 Go 语言中已经有了这样的功能。参考 VonC。
英文:
If what you are looking is indeed python list comprehension, there is no such syntactic equivalent in go AFAIK.
The way to do it is to create a function that take a slice and a function (to test the condition) and return a new slice.
EDIT:
Well looks like there is already such a feature in Go. cf VonC
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论