Golang: 内建容器的用法

1.数组

数组是值类型

[10]int 和 [20]int是不同类型

调用func(arr [10]int)会拷贝数组

在go语言中一般不直接使用数据

package main
import "fmt"
func updateArr(arr *[5]int) {
	arr[0] = 100
}
func updateArrThroughSlice(arr []int)  {
	arr[0] = 100
}
func main() {
	//创建一个数据
	var arr [5]int
	arr2 := [5]int{1, 2, 3, 4, 5}
	//长度让编译器来数
	arr3 := [...]int{1, 2, 3, 4, 5}
	//[0 0 0 0 0] [1 2 3 4 5] [1 2 3 4 5]
	fmt.Println(arr, arr2, arr3)
	//定义二维数组 4行5列
	var arr4 [4][5]int
	//[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
	fmt.Println(arr4)
	//遍历数据
	//for i:=0;i<len(arr3);i++{
	//	fmt.Println(arr3[i])
	//}
	for num, v := range arr2 {
		fmt.Printf("第%d个元素为:%d\n", num, v)
	}
	//数据是值类型,通过指针可以改变值的大小
	fmt.Println("update before")
	fmt.Println(arr2)
	updateArr(&arr2) //传入arr3的地址
	fmt.Println("update after")
	fmt.Println(arr2)

	//通过Slice改变数据
	fmt.Println("update before")
	fmt.Println(arr3)
	updateArrThroughSlice(arr3[:]) //传入Slice
	fmt.Println("update after")
	fmt.Println(arr3)
}

2.Slice(切片)

2.1 Slice的实现

Slice本身没有数据,是对底层array的一个view

Slice内部有个指针(ptr)指向开头的元素,Slice有长度(len),容量(cap);cap代表从指针(ptr)开始到数组(arr)末尾的长度,Slice在扩展的时候不能超过cap.

package main
import "fmt"
func updateSlice(s []int) {
	s[0] = 100
}
func main() {
	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
	//创建一个Slice
	s1 := arr[:]
	s2 := arr[2:6]
	fmt.Printf("s1:%v\ns2:%v\n", s1, s2)
	//改变Slice内部元素
	updateSlice(s2)
	fmt.Println(s2)
	//ReSlice:对Slice再进行一次Slice操作
	s3 := s1[:5]
	fmt.Println(s3)
	s3 = s3[:2]
	fmt.Println(s3)
}

2.2 Slice的扩展

s[i]不可以超越len(i),向后扩展不可以超过底层数组cap(s)

package main
import "fmt"
func updateSlice(s []int) {
	s[0] = 100
}
func main() {
	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
	fmt.Printf("arr=%v\n", arr)
	//Extending Slice 不能超过cap(s)
	s1 := arr[2:6]
	fmt.Printf("s1=%v, len(s1)=%d, cap(s1)=%d\n", s1, len(s1), cap(s1))
	s2 := s1[3:5]
	fmt.Printf("s2=%v, len(s2)=%d, cap(s2)=%d\n", s2, len(s2), cap(s2))
	// s[i]不能超过len(s)
	fmt.Printf("get Slice element:%v",s2[1])
	//panic: runtime error: index out of range [2] with length 2
	//fmt.Printf("get Slice element:%v",s2[2])
}

2.2 Slice的其它操作

向Slice添加元素

package main
import "fmt"
//查看操作系统怎么扩充Slice的cap
func printSlice(s []int) {
	fmt.Printf("%v, len=%d, cap=%d\n", s, len(s), cap(s))
}
func main() {
	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
	//添加元素时如果超越cap,系统会重新分配更大的底层数组
	//由于值传递的关系,必须接收append的返回值
	// s = append(s,val)
	s1 := arr[2:]
	fmt.Printf("s1=%v\n", s1)
	s2 := s1[3:5] //[s1[3], s1[4]]
	fmt.Printf("s2=%v, len(s2)=%d, cap(s2)=%d\n", s2, len(s2), cap(s2))
	s3 := append(s2, 10)
	s4 := append(s3, 11)
	s5 := append(s4, 12)
	fmt.Printf("s3=%v, s4=%v, s5=%v\n", s3, s4, s5)
	// s4 and s5 no longer view arr
	fmt.Printf("arr=%v\n", arr)
	//创建一个Slice
	var s []int
	//Zero value for slice is nil
	for i := 0; i < 100; i++ {
		printSlice(s)
		s = append(s, i*2+1)
	}
	fmt.Println(s)
}

Slice的copy,添加,删除元素操作

package main
import (
	"fmt"
)
//查看操作系统怎么扩充Slice的cap
func printSlice(str string, s []int) {
	fmt.Printf("%s=%v, len=%d, cap=%d\n", str, s, len(s), cap(s))
}
func main() {
	//初始化slice
	s1 := []int{2, 4, 6, 8}
	fmt.Println(s1)
	//[2 4 6 8]
	//创建一个len为16的Slice
	s2 := make([]int, 16)
	//创建一个len为10,cap为32的Slice
	s3 := make([]int, 10, 32)
	printSlice("s2", s2)
	//[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], len=16, cap=16
	printSlice("s3", s3)
	//[0 0 0 0 0 0 0 0 0 0], len=10, cap=32
	//拷贝Slice
	fmt.Println("Copying Slice")
	//dst src
	copy(s2, s1)
	printSlice("s2", s2)
	//[2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0], len=16, cap=16
	//删除Slice中的元素
	fmt.Println("Deleting element from slice")
	//删除下标为3的元素
	//通过...append s2下标为4后的元素
	s2 = append(s2[:3], s2[4:]...)
	printSlice("s2", s2)
	//删除头尾元素
	fmt.Println("Popping from front")
	front := s2[0]
	s2 = s2[1:]
	fmt.Println(front)
	fmt.Println(s2)
	fmt.Println("Popping from back")
	tail := s2[len(s2)-1]
	s2 = s2[:len(s2)-1]
	fmt.Println(tail)
	fmt.Println(s2)
}

3.Map

3.1 Map的操作

创建: make(map[string]int)

获取元素:m[key]

key不存在时,获得Value类型的初始值

用value,ok := m[key]来判断是否存在key

用delete删除一个key

使用range遍历key,或者遍历key, value对

不保证遍历顺序,如需顺序,需手动对key排序

使用len获得元素个数

package main
import "fmt"
func main() {
	//创建一个map
	//map中的key是无序的,是一个HashMap
	m := map[string]string{
		"name":    "Cocktail_py",
		"course":  "golang",
		"site":    "CSDN",
		"quality": "pretty well",
	}
	m2 := make(map[string]int) // m2 = empty map
	var m3 map[string]int      // m3 == nil
	fmt.Println(m, m2, m3)
	fmt.Println("Traversing map")
	for k, v := range m {
		fmt.Println(k, v)
	}
	//map 操作
	//获取元素:m[key]
	fmt.Println("Getting values")
	courseName, ok := m["course"]
	fmt.Println(courseName, ok)

	//当key不存在
	if courName, ok := m["courName"]; ok {
		fmt.Println(courName) // Zero value
	} else {
		fmt.Println("key does not exist")
	}

	fmt.Println("Deleting values")
	delete(m, "name")
	name, ok := m["name"]
	fmt.Println(name, ok)
}

3.2 Map的key

map使用哈希表,必须可以比较相等

除了Slice,map,function的内建类型都可以作为key

Struct类型不包含上述字段,也可作为key

3.3 Map的例题:寻找最长不含有重复字符的子串

/*
当前一个字符串,从左往后开始扫描,只要扫描一遍就可以,如果扫到X的位置,看到一个字母X应该怎么做呢
首先,记录一个start表示当前找到的最长不含有重复字符的子串的开始,保证start到X之前的子串是不含有重复字符的,
之后,需要查看从start到X-1这个位置之间有没有X,使用一个叫lastOccurred[x]记录X最后出现的位置在哪里,使用map会有三种情况:1.x重来没有出现过,或者x出现在start之前,若x出现在start之前,最长的子串+1; 2.lastOccurred[x]出现在start到X中间,更新start位置,start指向lastOccurred[x+1]的位置
*/
package main
import "fmt"
func lengthOfNonRepeatingSubStr(s string)int  {
	lastOccurred := make(map[byte]int)
	start := 0
	maxLength := 0
	//遍历字符串 go语言中char类型是使用了一种rune(32位)类型
	for x, ch := range []byte(s){
		//lastOccurred[ch]有可能不存在;若不存在出现0,会影响运算
		if lastl, ok:= lastOccurred[ch];ok && lastl >= start{
			start = lastl + 1
		}
		//stat到i结束
		if x-start + 1 > maxLength{
			maxLength = x -start + 1
		}
		lastOccurred[ch] = x
	}
	return maxLength
}
func main() {
	fmt.Println(lengthOfNonRepeatingSubStr("hellohello"))
}

4.rune

rune相当于go的char

使用range遍历pos,rune对

使用utf8.RuneCountlnString获得字符数量

使用len获得字节长度

使用[]byte获得字节

package main
import (
	"fmt"
	"unicode/utf8"
)
func main() {
	//英文占一个字节,中文占三个字节
	s := "yes我爱CSDN!"
	fmt.Println(len(s)) // 14
	//%X十六进制,大写字符,每个字节两个字符
	//796573E68891E788B14353444E21
	fmt.Printf("%X\n",[]byte(s))
	//%T 相应值的类型
	//使用for range遍历字符串时,会默认将byte(int8)类型转化为rune(int32)类型,因为go采用UTF-8编码 可变长的编码
	for _,b := range s{
		fmt.Printf("%T %X\n",b,b)
	}
	for _,b := range []byte(s){
		fmt.Printf("%T %X\n",b,b)
	}
	//打印字符的个数
	fmt.Println("Rune count:",utf8.RuneCountInString(s))
	bytes := []byte(s)
	fmt.Println(bytes)
	for len(bytes) > 0{
		ch,size := utf8.DecodeRune(bytes)
		bytes = bytes[size:]
		//相应Unicode码点所表示的字符
		fmt.Printf("%c",ch)
	}
	//获取第几个字符是谁
	for i, ch := range []rune(s) {
		fmt.Printf("(%d %c) ", i, ch)
	}
	fmt.Println()
}

4.1 Map的例题:寻找最长不含有重复字符的子串(国际版)

//国际版
func lengthOfNonRepeatingSubStr(s string) int {
	lastOccurred := make(map[rune]int)
	start := 0
	maxLength := 0
	//遍历字符串 go语言中char类型是使用了一种rune(32位)
	//for i, ch := range s{
	for i, ch := range []rune(s) {
		//lastOccurred[ch]有可能不存在;若不存在出现0,会影响运算
		if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
			start = lastI + 1
		}
		//start到i结束
		if i-start+1 > maxLength {
			maxLength = i - start + 1
		}
		lastOccurred[ch] = i
	}
	return maxLength
}

补充:Golang 容器的学习与实践

Golang 提供了几个简单的容器供我们使用,本文在介绍几种 Golang 容器的基础上,实现一个基于 Golang 容器的LRU算法。

容器介绍

Golang 容器位于 container 包下,提供了三种包供我们使用,heap、list、ring. 下面我们分别学习。

heap

heap 是一个堆的实现。一个堆正常保证了获取/弹出最大(最小)元素的时间为log n、插入元素的时间为 log n.

Golang堆实现接口如下:

// src/container/heap.go
type Interface interface {
 sort.Interface
 Push(x interface{}) // add x as element Len()
 Pop() interface{} // remove and return element Len() - 1.
}

heap 是基于 sort.Interface 实现的。

// src/sort/
type Interface interface {
 Len() int
 Less(i, j int) bool
 Swap(i, j int)
}

因此,如果要使用官方提供的 heap,需要我们实现如下几个接口:

Len() int {} // 获取元素个数
Less(i, j int) bool  {} // 比较方法
Swap(i, j int) // 元素交换方法
Push(x interface{}){} // 在末尾追加元素
Pop() interface{} // 返回末尾元素

然后在使用时,我们可以使用如下几种方法:

// 初始化一个堆
func Init(h Interface){}
// push一个元素倒堆中
func Push(h Interface, x interface{}){}
// pop 堆顶元素
func Pop(h Interface) interface{} {}
// 删除堆中某个元素,时间复杂度 log n
func Remove(h Interface, i int) interface{} {}
// 调整i位置的元素位置(位置I的数据变更后)
func Fix(h Interface, i int){}

list 链表

list 实现了一个双向链表,链表不需要实现 heap 类似的接口,可以直接使用。

链表的构造:

// 返回一个链表对象
  func New() *List {}

官方提供了丰富的方法供我们操作列表,方法如下:

// 返回链表的长度
func (l *List) Len() int {}
// 返回链表中的第一个元素
func (l *List) Front() *Element {}
// 返回链表中的末尾元素
func (l *List) Back() *Element {}
// 移除链表中的某个元素
func (l *List) Remove(e *Element) interface{} {}
// 在表头插入值为 v 的元素
func (l *List) PushFront(v interface{}) *Element {}
// 在表尾插入值为 v 的元素
func (l *List) PushBack(v interface{}) *Element {}
// 在mark之前插入值为v 的元素
func (l *List) InsertBefore(v interface{}, mark *Element) *Element {}
// 在mark 之后插入值为 v 的元素
func (l *List) InsertAfter(v interface{}, mark *Element) lement {}
// 移动e某个元素到表头
func (l *List) MoveToFront(e *Element) {}
// 移动e到队尾
func (l *List) MoveToBack(e *Element) {}
// 移动e到mark之前
func (l *List) MoveBefore(e, mark *Element) {}
// 移动e 到mark 之后
func (l *List) MoveAfter(e, mark *Element) {}
// 追加到队尾
func (l *List) PushBackList(other *List) {}
// 将链表list放在队列前
func (l *List) PushFrontList(other *List) {}

我们可以通过 Value 方法访问 Element 中的元素。除此之外,我们还可以用下面方法做链表遍历:

// 返回下一个元素
func (e *Element) Next() *Element {}
// 返回上一个元素
func (e *Element) Prev() *Element {}
下面是队列的遍历的例子:
// l 为队列,
for e := l.Front(); e != nil; e = e.Next() {
  //通过 e.Value 做数据访问
}

ring 循环列表

container 中的循环列表是采用链表实现的。

// 构造一个包含N个元素的循环列表
func New(n int) *Ring {}
// 返回列表下一个元素
func (r *Ring) Next() *Ring {}
// 返回列表上一个元素
func (r *Ring) Prev() *Ring {}
// 移动n个元素 (可以前移,可以后移)
func (r *Ring) Move(n int) *Ring {}
// 把 s 链接到 r 后面。如果s 和r 在一个ring 里面,会把r到s的元素从ring 中删掉
func (r *Ring) Link(s *Ring) *Ring {}
// 删除n个元素 (内部就是ring 移动n个元素,然后调用Link)
func (r *Ring) Unlink(n int) *Ring {}
// 返回Ring 的长度,时间复杂度 n
func (r *Ring) Len() int {}
// 遍历Ring,执行 f 方法 (不建议内部修改ring)
func (r *Ring) Do(f func(interface{})) {}

访问 Ring 中元素,直接 Ring.Value 即可。

容器的使用

下面,我们通过 map 和 官方包中的双向链表实现一个简单的 lru 算法,用来熟悉golang 容器的使用。

LRU 算法 (Least Recently Used),在做缓存置换时用的比较多。逐步淘汰最近未使用的 cache,而使我们的缓存中持续保持着最近使用的数据。

package main
import "fmt"
import "container/list"

// lru 中的数据
type Node struct {
  K, V interface{}
}

// 链表 + map
type LRU struct {
  list *list.List
  cacheMap map[interface{}]*list.Element
  Size int
}

// 初始化一个LRU
func NewLRU(cap int) *LRU {
  return &LRU{
    Size: cap,
    list: list.New(),
    cacheMap: make(map[interface{}]*list.Element, cap),
  }
}

// 获取LRU中数据
func (lru *LRU) Get(k interface{}) (v interface{}, ret bool) {
  // 如果存在,则把数据放到链表最前面
  if ele, ok := lru.cacheMap[k]; ok {
    lru.list.MoveToFront(ele)
    return ele.Value.(*Node).V, true
  }
  return nil, false
}
// 设置LRU中数据
func (lru *LRU) Set(k, v interface{}) {
  // 如果存在,则把数据放到最前面
  if ele, ok := lru.cacheMap[k]; ok {
    lru.list.MoveToFront(ele)
    ele.Value.(*Node).V = v // 更新数据值
    return
  }
  // 如果数据是满的,先删除数据,后插入
  if lru.list.Len() == lru.Size {
    last := lru.list.Back()
    node := last.Value.(*Node)
    delete(lru.cacheMap, node.K)
    lru.list.Remove(last)
  }  ele := lru.list.PushFront(&Node{K: k, V: v})
  lru.cacheMap[k] = ele
}

注意事项

上述的容器都不是 goroutines 安全的

1、上面的lr 也不是 goroutines 安全的

2、Ring 中不建议在 Do 方法中修改 Ring 的指针,行为是未定义的

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • golang 定时任务方面time.Sleep和time.Tick的优劣对比分析

    golang 写循环执行的定时任务,常见的有以下三种实现方式 1.time.Sleep方法: for { time.Sleep(time.Second) fmt.Println("我在定时执行任务") } 2.time.Tick函数: t1:=time.Tick(3*time.Second) for { select { case <-t1: fmt.Println("t1定时器") } } 3.其中Tick定时任务 也可以先使用time.Ticker函数获取

  • golang日志包logger的用法详解

    1. logger包介绍 import "github.com/wonderivan/logger" 在我们开发go程序的过程中,发现记录程序日志已经不是fmt.print这么简单,我们想到的是打印输出能够明确指定当时运行时间.运行代码段,当然我们可以引入go官方自带包 import "log",然后通过log.Printf.log.Println等方式输出,而且默认是日志输出时只带时间的,想要同时输出所运行代码段位置,还需要通过执行一下指定进行相关简单的设置 lo

  • Golang的func参数及返回值操作

    参数及返回值 参数一指定数据类型为int 参数二 (-interface{}) 可传任何多个不同类型的参数 返回值:单个返回值直接指定数据类型可以不使用 (),多个返回值需使用().各返回值之间使用逗号分隔 func main() { demo.Params(10, 20, "golang", true) } func Params(id int, params ...interface{}) (error, error) { fmt.Println(id) fmt.Println(p

  • golang协程池模拟实现群发邮件功能

    比如批量群发邮件的功能 因为发送邮件是个比较耗时的操作, 如果是传统的一个个执行 , 总体耗时比较长 可以使用golang实现一个协程池 , 并行发送邮件 pool包下的pool.go文件 package pool import "log" //具体任务,可以传参可以自定义操作 type Task struct { Args interface{} Do func(interface{})error } //协程的个数 var Nums int //任务通道 var JobChanne

  • 浅谈golang 中time.After释放的问题

    在谢大群里看到有同学在讨论time.After泄漏的问题,就算时间到了也不会释放,瞬间就惊呆了,忍不住做了试验,结果发现应该没有这么的恐怖的,是有泄漏的风险不过不算是泄漏, 先看API的说明: // After waits for the duration to elapse and then sends the current time // on the returned channel. // It is equivalent to NewTimer(d).C. // The underl

  • golang实现对docker容器心跳监控功能

    自己写的go程序放到线上本来编译成二进制扔上去就行啦,但是怀着一颗docker的心,最终还是将它放到docker容器中运行起来了,运行起来也ok,一个最小容器64M,统一管理起来也方便,但是毕竟是个线上长驻内存的服务程序,万一跑挂了怎么办,如何才能监控它,直接上go代码,网上代码,略微做了下注释,但实测过,真实有效: package main import ( "encoding/json" "errors" "flag" "fmt&q

  • golang elasticsearch Client的使用详解

    elasticsearch 的client ,通过 NewClient 建立连接,通过 NewClient 中的 Set.URL设置访问的地址,SetSniff设置集群 获得连接 后,通过 Index 方法插入数据,插入后可以通过 Get 方法获得数据(最后的测试用例中会使用 elasticsearch client 的Get 方法) func Save(item interface{}) { client, err := elastic.NewClient( elastic.SetURL("h

  • golang 比较浮点数的大小方式

    Golang浮点数比较和运算会出现误差. 浮点数储存至内存中时,2的-1.-2---n次方不能精确的表示小数部分,所以再把这个数从地址中取出来进行计算就出现了偏差. package main import ( "errors" "fmt" "github.com/shopspring/decimal" ) func FloatCompare(f1, f2 interface{}) (n int, err error) { var f1Dec, f

  • Golang: 内建容器的用法

    1.数组 数组是值类型 [10]int 和 [20]int是不同类型 调用func(arr [10]int)会拷贝数组 在go语言中一般不直接使用数据 package main import "fmt" func updateArr(arr *[5]int) { arr[0] = 100 } func updateArrThroughSlice(arr []int) { arr[0] = 100 } func main() { //创建一个数据 var arr [5]int arr2

  • JSP 开发之Struts2内建自定义拦截器

    JSP 开发之Struts2内建自定义拦截器 Struts2的自定义拦截器主要用于解析请求参数,将请求参数赋值给Action属性,执行数据校验,文件上传等等操作.当需要扩展Struts2的功能时,我们只需要提供相应的拦截器并将它配置到Struts2容器中即可:当我们不需要使用的时候,只需要取消它在Struts2容器中的配置就行了. 1>配置拦截器主要使用四个配置元素: :用于配置自定义拦截器 :用于引用拦截器或者拦截器栈 :用于配置自定义拦截器栈,一个拦截器栈由多个拦截器构成,也可以包含其他的拦

  • Python内建数据结构详解

    一.列表(List) list 是一个可以在其中存储一系列项目的数据结构.list 的项目之间需用逗号分开,并用一对中括号括将所有的项目括起来,以表明这是一个 list .下例用以展示 list 的一些基本操作: # 定义一个 list 对象 class_list: class_list = ['Michael', 'Bob', 'Tracy'] # 获得一个 class_list 的长度 print 'class have', len(class_list), 'students' # 访问c

  • golang模板template自定义函数用法示例

    本文实例讲述了golang模板template自定义函数用法.分享给大家供大家参考,具体如下: golang的模板十分强大,其中的unix管道风格函数调用很是喜欢. 模板中有很多内置可以参看pkg文档, 另外还可以实现自定义函数. 例子如下: 复制代码 代码如下: package main import (     "text/template"     "time"     "os" ) type User struct {     Usern

  • LINUX中详解AWK内建变量FS,NF,NR,RT,RS,ORS,OFS

    看了网上好多关于AWK内建变量的文章,这里加上个人的理解和记忆,可以让大家掌握这些变量的基本用法. FS 指定字段un列分隔符(Font Space) [~/AWK_learning]$ echo "111|222|333" | awk '{print $1}' 111|222|333 [~/AWK_learning]$ echo "111|222|333" | awk 'BEGIN{FS="|"}{print $1}' 111 OFS 指定输出

  • 了解一下python内建模块collections

    在使用Python的过程中,一定是离不开数据结构的, 也就是List-列表,Tuples-元组,Dictionaries-字典. 那实际应用中我们更多的还是要去操作这些结构里的数据.比如,在列表后面添加元素,那么就会用到append() 方法. 那除了这些本身的操作方法之外,还有一个Python内建模块--collections,也提供了不少使用的方法,今天来捋一下. 一.Counter 这是一个计数器,我们可以用来方便的统计出一些元素出现的次数,比如String.List.Tuples等等.

  • Python内建属性getattribute拦截器使用详解

    目录 引言 1.内建属性__getattribute__的用法 2.重写__getattribute__实现属性拦截功能 总结要点: 引言 因为python中所有类默认继承object类. 而object类提供了了很多原始的内建属性和方法,所以用户自定义的类在Python中也会继承这些内建属性. 可以使用dir()函数可以查看,虽然python提供了很多内建属性但实际开发中常用的不多.而很多系统提供的内建属性实际开发中用户都需要重写后才会使用. 对于python来说,属性或者函数都可以被理解成一

  • Python内建类型list源码学习

    目录 问题: 1 常用方法 小结: 题外话: 2 list的内部结构:PyListObject 3 尾部操作和头部操作 3.1 尾部操作 3.2 头部操作 4 浅拷贝和深拷贝 4.1 浅拷贝 4.2 深拷贝 4.3 直接赋值 4.4 小结 个人总结: TODO: 5 动态数组 5.1 容量调整 5.2 append() 5.3 insert() 5.4 pop() 5.5 remove() 6 一些问题 问题: “深入认识Python内建类型”这部分的内容会从源码角度为大家介绍Python中各种

  • 语言编程花絮内建构建顺序示例详解

    目录 1 构建 顺序 1.1 交叉编译 1.2 设置 2 构建测试支持 1 构建 顺序 依据词法名顺序 当导入一个包,且这个包 定义了 init(), 那么导入时init()将被执行. 具体执行顺序: 全局变量定义时的函数 import 执行导入 -> cont 执行常量 --> var 执行变量 --> 执行初始化 init() --> 执行 main() ----> main import pk1 ---> pk1 const ... import pk2 ---&

  • Python中3种内建数据结构:列表、元组和字典

    Python中有3种内建的数据结构:列表.元组和字典.参考简明Python教程 1. 列表 list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个 序列 的项目.假想你有一个购物列表,上面记载着你要买的东西,你就容易理解列表了.只不过在你的购物表上,可能每样东西都独自占有一行,而在Python中,你在每个项目之间用逗号分割. 列表中的项目应该包括在方括号中,这样Python就知道你是在指明一个列表.一旦你创建了一个列表,你可以添加.删除或是搜索列表中的项目.由于你可以增加或删除项目,

随机推荐