Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent for Python's list comprehension

Tags:

python

go

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))
like image 544
Spearfisher Avatar asked Jan 08 '15 19:01

Spearfisher


People also ask

What is the list comprehension in Python?

List comprehension is an elegant way to define and create lists based on existing lists. List comprehension is generally more compact and faster than normal functions and loops for creating list.

Is list comprehension faster than for loop Python?

Because of differences in how Python implements for loops and list comprehension, list comprehensions are almost always faster than for loops when performing operations.

Is there string comprehension in Python?

List comprehension in Python is an easy and compact syntax for creating a list from a string or another list. It is a very concise way to create a new list by performing an operation on each item in the existing list. List comprehension is considerably faster than processing a list using the for loop.


2 Answers

Interestingly enough, Rob Pike just proposed (18 hours ago) the library filter which does a bit what you want:

See for instance Choose()

// 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.

Tested here:

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.

like image 197
VonC Avatar answered Oct 22 '22 07:10

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

like image 3
Félix Cantournet Avatar answered Oct 22 '22 07:10

Félix Cantournet