In Python, I have the following:

i = series.index(s) # standard Python list.index() function tmp = series.pop(i) blah = f(tmp) series.append(tmp) 

In converting this to Go, I am looking for a similar way of retrieving an item from a slice by index, doing something with it, then putting the original item at the end of my slice.

From here, I have arrived at the following:

i = Index(series, s) // my custom index function... tmp, series = series[i], series[i+1:] blah := f(tmp) series = append(series, tmp) 

But this fails at the end of lists:

panic: runtime error: slice bounds out of range 

How would I idiomatically translate this slice.pop() into Go?

7

6 Answers

The "Cut" trick in the linked document does what you want:

xs := []int{1, 2, 3, 4, 5} i := 0 // Any valid index, however you happen to get it. x := xs[i] xs = append(xs[:i], xs[i+1:]...) // Now "x" is the ith element and "xs" has the ith element removed. 

Note that if you try to make a one-liner out of the get-and-cut operations you'll get unexpected results due to the tricky behavior of multiple assignments in which functions are called before other expressions are evaluated:

i := 0 x, xs := xs[i], append(xs[:i], xs[i+1:]...) // XXX: x=2, xs=[]int{2, 3, 4, 5} 

You can work around by wrapping the element access operation in any function call, such as the identity function:

i := 0 id := func(z int) { return z } x, xs := id(xs[i]), append(xs[:i], xs[i+1:]...) // OK: x=1, xs=[]int{2, 3, 4, 5} 

However, at that point it's probably more clear to use separate assignments.

For completeness, a "cut" function and its usage could look like this:

func cut(i int, xs []int) (int, []int) { y := xs[i] ys := append(xs[:i], xs[i+1:]...) return y, ys } t, series := cut(i, series) f(t) series = append(series, t) 
1

If you want to write a function that does pop() in a similar way to python then you'll have to pass in a pointer to the object so the object can be modified, as pop both returns the value and alters the list

func pop(alist *[]int) int { f:=len(*alist) rv:=(*alist)[f-1] *alist=(*alist)[:f-1] return rv } func main() { n:=[]int{1,2,3,4,5} fmt.Println(n) last:=pop(&n) fmt.Println("last is",last) fmt.Printf("list of n is now %v\n", n) 
2

You can declaretype intSlice []int and you can declare method pop() using that pointer receiver: func (l *intSlice) pop() int. Then you can call .pop() on instance of intSlice object. This becomes stylistically more similar to Python.

package main import ( "fmt" ) type intSlice []int func (l *intSlice) pop() int { length := len(*l) lastEle := (*l)[length-1] *l = (*l)[:length-1] return lastEle } func main() { mySlice := intSlice{1, 2, 3, 4, 5, 6} popped := mySlice.pop() fmt.Println(popped) fmt.Println(mySlice) popped = mySlice.pop() fmt.Println(popped) fmt.Println(mySlice) } 

Result:

6 [1 2 3 4 5] 5 [1 2 3 4] 

Go Playground

I'm not sure there's a direct equivalent of "pop()" ... but you can do something like this:

A Tour of Go

Slices can be created with the built-in make function; this is how you create dynamically-sized arrays.

The make function allocates a zeroed array and returns a slice that refers to that array:

a := make([]int, 5) // len(a)=5

To specify a capacity, pass a third argument to make:

b := make([]int, 0, 5) // len(b)=0, cap(b)=5

b = b[:cap(b)] // len(b)=5, cap(b)=5

b = b[1:] // len(b)=4, cap(b)=4

See also:

I'd do something similar to what paulsm4 suggested:

package main import ( "fmt" ) func main() { a := []int{1,2,3,4,5} i,b := pop(a) fmt.Println(i,b) // 5 [1 2 3 4] } func pop(a []int) (int,[]int) { return a[len(a)-1],a[:len(a)-1] } 

Go playground

2

Another option would be to create a function that takes a pointer to an int slice which modifies the argument to remove the last value and return it:

func pop(xs *[]int) int { x := (*xs)[len(*xs)-1] // Store the last value to return. *xs = (*xs)[:len(*xs)-1] // Remove the last value from the slice. return x } 

For example (Go Playground):

xs := []int{1, 2, 3} // => xs=[1, 2, 3] x := pop(&xs) // => xs=[1, 2], x=3 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy