• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Python与Go列表切片越界的对比

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

需求

很简单的知识点,做一下小结。

最近写代码需要做一下切片的操作,比如给定这样一个切片:

lst1 = [1,2,3,4,5,6,7,8,9,10,11,12,13]

将这个切片里面的元素按照每4个为一组,每一组组成单独的切片,然后再组合到外层的切片中,结果像这样:

[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13]]

python的写法

# -*- coding:utf-8 -*-

lst1 = [1,2,3,4,5,6,7,8,9,10,11,12,13]
lst2 = ["w","wg","wa","jj","aa","ff","gg","hh","asd","ww","ee","gg","nn","mm"]

print(len(lst1)) # 13
print(len(lst2)) # 14

### 超限切片
ret_lst1 = list()
ret_lst2 = list()

# 根据lst1构建新的列表
for i in range(0,len(lst1),4):
    curr_lst = lst1[i:i+4]
    ret_lst1.append(curr_lst)

# 根据lst2构建新的列表
for i in range(0,len(lst2),4):
    curr_lst = lst2[i:i+4]
    ret_lst2.append(curr_lst)

### 注意结果最后一个列表不足的话不会报错
print(ret_lst1) # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13]]
print(ret_lst2) # [[\'w\', \'wg\', \'wa\', \'jj\'], [\'aa\', \'ff\', \'gg\', \'hh\'], [\'asd\', \'ww\', \'ee\', \'gg\'], [\'nn\', \'mm\']]

Go的写法

错误的写法

package t9

import (
    "fmt"
    "testing"
)


func TestOutRange(t *testing.T) {
    lst1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
    lst2 := []string{"w", "wg", "wa", "jj", "aa", "ff", "gg", "hh", "asd", "ww", "ee", "gg", "nn", "mm"}

    fmt.Println(len(lst1)) // 13
    fmt.Println(len(lst2)) // 14

    // 结果
    var retLst1 [][]int
    var retLst2 [][]string

    // 超限切片
    for i := 0; i < len(lst1); i += 4 {
        currLst := lst1[i : i+4]
        retLst1 = append(retLst1, currLst)
    }

    for i := 0; i < len(lst2); i += 4 {
        currLst := lst2[i : i+4]
        retLst2 = append(retLst2, currLst)
    }

}

这样写会上报一个错误:

--- FAIL: TestOutRange (0.00s)
panic: runtime error: slice bounds out of range [:16] with capacity 13 [recovered]
    panic: runtime error: slice bounds out of range [:16] with capacity 13

错误的原因是,我们每次获取currLst的时候,是按照 lst[i i+4] 这样直接切片的,但是,如果i+4大于列表lst的长度的话,会上报越界错误!

正确的写法 ***

既然i+4可能会超出lst的长度越界,那我们在切片的时候判断一下二者的大小即可:

package t9

import (
    "fmt"
    "testing"
)

// 返回两个int最小的那个
func minInt(a, b int) int {
    if a < b {
        return a
    }
    return b
}

func TestOutRange(t *testing.T) {
    lst1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
    lst2 := []string{"w", "wg", "wa", "jj", "aa", "ff", "gg", "hh", "asd", "ww", "ee", "gg", "nn", "mm"}

    fmt.Println(len(lst1)) // 13
    fmt.Println(len(lst2)) // 14

    // 结果
    var retLst1 [][]int
    var retLst2 [][]string

    // 切片
    for i := 0; i < len(lst1); i += 4 {
        // 保证不越界
        currLst := lst1[i:minInt(i+4, len(lst1))]
        retLst1 = append(retLst1, currLst)
    }

    for i := 0; i < len(lst2); i += 4 {
        // 保证不越界
        currLst := lst2[i:minInt(i+4, len(lst2))]
        retLst2 = append(retLst2, currLst)
    }

    // 注意结果有填充的默认值
    fmt.Println(retLst1) // [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13]]
    fmt.Println(retLst2) // [[w wg wa jj] [aa ff gg hh] [asd ww ee gg] [nn mm]]
}

~~~


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Python和GO语言之间的区别是什么?发布时间:2022-07-10
下一篇:
python与go的一些区别发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap