为了账号安全,请及时绑定邮箱和手机立即绑定

如何在golang中实现python`zip`功能?

如何在golang中实现python`zip`功能?

Go
MYYA 2021-08-30 16:28:47
有时,使用zipPython 中的内置函数将两个列表组合成一个元组是很方便的。如何在 golang 中类似地做到这一点?
查看完整描述

2 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

你可以做这样的事情这样,你给元组类型的名称:


package main


import "fmt"


type intTuple struct {

    a, b int

}


func zip(a, b []int) ([]intTuple, error) {


    if len(a) != len(b) {

        return nil, fmt.Errorf("zip: arguments must be of same length")

    }


    r := make([]intTuple, len(a), len(a))


    for i, e := range a {

        r[i] = intTuple{e, b[i]}

    }


    return r, nil

}


func main() {

    a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}

    b := []int{0, 9, 8, 7, 6, 5, 4, 3, 2, 1}

    fmt.Println(zip(a, b))

}

或者为元组使用未命名的类型,如下所示:


package main


import "fmt"


func zip(a, b []int) ([][3]int, error) {


    if len(a) != len(b) {

        return nil, fmt.Errorf("zip: arguments must be of same length")

    }


    r := make([][4]int, len(a), len(a))


    for i, e := range a {

        r[i] = [2]int{e, b[i]}

    }


    return r, nil

}


func main() {

    a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}

    b := []int{0, 9, 8, 7, 6, 5, 4, 3, 2, 1}

    fmt.Println(zip(a, b))

}

最后,这是一种软通用的方法:


package main


import (

    "fmt"

    "reflect"

)


func zip(a, b, c interface{}) error {


    ta, tb, tc := reflect.TypeOf(a), reflect.TypeOf(b), reflect.TypeOf(c)


    if ta.Kind() != reflect.Slice || tb.Kind() != reflect.Slice || ta != tb {

        return fmt.Errorf("zip: first two arguments must be slices of the same type")

    }


    if tc.Kind() != reflect.Ptr {

        return fmt.Errorf("zip: third argument must be pointer to slice")

    }


    for tc.Kind() == reflect.Ptr {

        tc = tc.Elem()

    }


    if tc.Kind() != reflect.Slice {

        return fmt.Errorf("zip: third argument must be pointer to slice")

    }


    eta, _, etc := ta.Elem(), tb.Elem(), tc.Elem()


    if etc.Kind() != reflect.Array || etc.Len() != 2 {

        return fmt.Errorf("zip: third argument's elements must be an array of length 2")

    }


    if etc.Elem() != eta {

        return fmt.Errorf("zip: third argument's elements must be an array of elements of the same type that the first two arguments are slices of")

    }


    va, vb, vc := reflect.ValueOf(a), reflect.ValueOf(b), reflect.ValueOf(c)


    for vc.Kind() == reflect.Ptr {

        vc = vc.Elem()

    }


    if va.Len() != vb.Len() {

        return fmt.Errorf("zip: first two arguments must have same length")

    }


    for i := 0; i < va.Len(); i++ {

        ea, eb := va.Index(i), vb.Index(i)

        tt := reflect.New(etc).Elem()

        tt.Index(0).Set(ea)

        tt.Index(1).Set(eb)

        vc.Set(reflect.Append(vc, tt))

    }


    return nil

}


func main() {


    a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}

    b := []int{0, 9, 8, 7, 6, 5, 4, 3, 2, 1}

    c := [][2]int{}


    e := zip(a, b, &c)


    if e != nil {

        fmt.Println(e)

        return

    }


    fmt.Println(c)

}


查看完整回答
反对 回复 2021-08-30
?
隔江千里

TA贡献1906条经验 获得超10个赞

对于zip一些切片[]int列表,


package main


import "fmt"


func zip(lists ...[]int) func() []int {

    zip := make([]int, len(lists))

    i := 0

    return func() []int {

        for j := range lists {

            if i >= len(lists[j]) {

                return nil

            }

            zip[j] = lists[j][i]

        }

        i++

        return zip

    }

}


func main() {

    a := []int{1, 2, 3}

    b := []int{4, 5, 6}

    c := []int{7, 8, 9, 0}

    iter := zip(a, b, c)

    for tuple := iter(); tuple != nil; tuple = iter() {

        fmt.Println("tuple:", tuple)

    }

}

输出:


元组:[1 4 7]

元组:[2 5 8]

元组:[3 6 9]


查看完整回答
反对 回复 2021-08-30
  • 2 回答
  • 0 关注
  • 306 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信