首页 > 代码库 > 列表、字典、元组进阶

列表、字典、元组进阶

  列表、字典和元组是python中所有脚本的主要工作组件。

列表

  列表中可包含任意种类的对象。和字符串一样,他也支持序列的常规操作,指定偏移值和切片、合并以及迭代等序列操作。

  与其他语言不同的是列表是一种高阶的序列操作工具,python中的列表可以完成大多数几何体数据结构的工作。

  列表的主要属性:

  1.任意对象的有序集合:列表中收集任何python对象并且保持了从左往右的位置顺序;

  2.通过偏移量读取;

  3.可变长度、异构和任意长度:列表是可变数据类型,支持原处修改,其中元素可以是任意数据类型,包括列表字典。

  4.对象引用:python总是会存储对象的引用而不是对象的copy。

  :我们在学习时注重精通常量语法,但是现实生产中python的多数据结构都是建立在运行执行程序代码时。

  列表的常规操作:

a=[1,2,a]
b=[a,s,d]
print(a+b)
print(a*2)
运行结果:
[1, 2, a, a, s, d]
[1, 2, a, 1, 2, a]

  列表的迭代与解析:

for i in a:
    print(i**2)
运行结果:
1
4
9
a=[1,2,3]
print(i**2 for i in a)
print(list(i**2 for i in a))
运行结果:
<generator object <genexpr> at 0x00000000027EBB40>
[1, 4, 9]
a=[-1,2,3]
print(list(map(abs, a)))
运行结果:
[1, 2, 3]

  由于列表多次嵌套,所以有时需要多次索引才能深入到数据结构中。

a=[[1,2,3],
   [4,5,6],
   [7,8,9]]
print(a[2][1])
运行结果:
8

  切片赋值时被赋值序列长度可以与我们复制的序列长度不相同,故可以用此操作进行替换,插入,缩短主列表。并且赋值的值与切片重合也是切实可行的。例:a[2:5]=a[3:7]。

  列表的常用方法:

  append():与a+[x]不同的是,方法原地修改列表,而+会产生新的列表。所以append方法执行更快。

a=[1,2,3]
a.append(4)
print(a)
运行结果:
[1, 2, 3, 4]

  sort():可以给定配置选项,name=value来定义。

a=[aBC,abd,Abe]
a.sort()
print(a)
a.sort(key=str.upper,reverse=True)
print(a)
运行结果:
[Abe, aBC, abd]
[Abe, abd, aBC]

  :在python2中比较时int总比str小,比较运算并不会自动转换类型,到了python3以后类型之间有了明确的界限,[1,2,‘a‘]这用列表已经不可以用sort方法排序了。

a=[aBC,abd,Abe]
print(sorted(a))
运行结果:
[Abe, aBC, abd]

  其他常用方法:

a=[aBC,abd,Abe]
a.extend([a])
print(a)
运行结果:
[aBC, abd, Abe, a]
a=[aBC,abd,Abe]
a.pop()
print(a)
运行结果:
[aBC, abd]
a=[aBC,abd,Abe]
a.reverse()
print(a)
print(list(reversed(a)))
运行结果:
[Abe, abd, aBC]
[aBC, abd, Abe]
a=[aBC,abd,Abe]
a.insert(0,a)
print(a)
print(a.index(a))
a.remove(a)
print(a)
print(a.pop(1))
运行结果:
[a, aBC, abd, Abe]
0
[aBC, abd, Abe]
abd

  注:a[i:j]=[]可以做到删除,但是a[i]=[]只会将此索引位置改为空列表。

字典:

  字典是一种无序的集合,是靠key来取值的序列。字典可以非常快速的进行一些其他语言的搜索算法和数据结构。

  字典的主要属性:

  1.通过key而不是偏移量取值:字典有自己的hash表,通过键来取值。

  2.任意对象无需集合:字典并没有特定的顺序,实际上key提供了象征性的位置作用。

  3.与列表一样字典可变长、异构、任意嵌套。

  4.属于可变映射类型。

  5.对象引用表:采用最优化的散列算法来寻找key,搜索速度极快,并且与列表一样存储对象是引用而不是拷贝。

  字典的常用操作:

a={name:jeff,age:111}
print(list(a.keys()))
运行结果:
[name, age]
a={name:jeff,age:111}
print(name in a)
运行结果:
Ture
a={name:jeff,age:111}
a[name]=frank
print(a)
运行结果:
{name: frank, age: 111}
a={name:jeff,age:111}
a[like]=game
print(a)
运行结果:
{name: jeff, like: game, age: 111}
a={name:jeff,age:111}
a[like]=game
del a[like]
print(a)
运行结果:
{age: 111, name: jeff}

  字典常用方法:

a={name:jeff,age:111}
print(list(a.values()))
print(list(a.items()))
运行结果:
[jeff, 111]
[(name, jeff), (age, 111)]

  get():检查key是否在,并返回某个值,默认None。

a={name:jeff,age:111}
print(a.get(name,no))
print(a.get(like,no))
运行结果:
jeff
no

  update():更新没有的,并且盲目覆盖已有的值。

a={‘name‘:‘jeff‘,‘age‘:‘111‘}
a.update({‘like‘:‘game‘})
print(a)
运行结果:
{‘name‘: ‘jeff‘, ‘like‘: ‘game‘, ‘age‘: ‘111‘}

  pop():

a={‘name‘:‘jeff‘,‘age‘:‘111‘}
a.pop(‘age‘)
print(a)
运行结果:
{‘name‘: ‘jeff‘}

  :字典的键不一定都是字符串,当然不可能是列表啦,字典的键可以是任何不可变对象。

  小技巧:制作一个字典让他用起来很像一个列表。

a={0:jeff,1:111}
print(a[0])
运行结果:
jeff

  值得一提的是读取不存在的键时常会报错,而在一些场景我们并不希望报错,我们可以采取以下三种方式进行避免:

  1.if先对键进行判断再使用。

a={0:jeff,1:111}
if 2 in a:
    print(a[0])
else:
    print(none)
运行结果:
none

  2.try语句修复

a={0:jeff,1:111}
try:
    print(a[2])
except KeyError:
    print(none)
运行结果:
none

  3.get()

a={0:jeff,1:111}
print(a.get(2,none))
运行结果:
none

  字典取代了搜索数据结构,在嵌套时轻松表达结构化信息。

  :字典接口适用于python各种内置工具。

  字典的4中创建方法:

a={0:jeff,1:111}
print(a)
运行结果:
{0: jeff, 1: 111}
a={}
a[name]=jeff
print(a)
运行结果:
{name: jeff}
a=dict(name=jeff)
print(a)
运行结果:
{name: jeff}
a=dict([(name,jeff)])
print(a)
运行结果:
{name: jeff}

   如果事先就能拼出整个字典,就使用第一种创建方式,如果需要动态创建字典的某个字段则使用第二种方式,第三种方式的key必须是字符串,第四种方式需要在运行时把key好的value逐步建成序列。

  python3中字典做出了哪些改变:

  1.支持字典解析表达式;

  2.调用a.keys、a.values、a.items方法需要使用list使其可视化;

  3.不再支持大小比较,相等性测试依然存在;

  4.取消has_key方法,只使用in判断成员关系,当然get方法也是可行的。

  字典解析:

a={k:v for (k,v) in zip([1,2,3],[a,s,d])}
print(a)
运行结果:
{1: a, 2: s, 3: d}

  keys,values,items返回的都是可迭代视图对象,如果想用列表操作或者显示他们的值,必须通过内置函数list来完成。当然这种试图既然是可迭代对象,我们还可以使用for循环迭代查看。此外遍历key的方法直接使用for i in {}即可,不一定要是用key方法。并且python3可以动态反映在视图创建对象后对字典做出的修改。

  :python2keys不会反回一个列表,所以python2需要通过排序键来浏览一个字典的编码模式。

  小练习:创建字典,所有键的value都是0。

a={‘a‘:0,‘b‘:0...}
print(a)
a={}
a[a]=0
a[b]=0
.
.
.
print(a)
a=dict(a=0,b=0...)
print(a)
a=dict([(a,0),(b,0)...])
print(a)
a=dict.fromkeys([a,b...],0)
print(a)
a={k:0 for k in ab...}
print(a)

元组

  元组基本属性:

  1.任意对象有序集合:这点与列表一致;

  2.通过偏移存取;

  3.固定长度、异构任意嵌套:因为元组是不可变序列类型;

  4.引用对象而非copy。

  元组和其他两种序列不同的是他没有方法,还是因为他的不可变性,可能根本就不需要什么方法吧。

  这里值得注意的是定义只有单个元素的元组的情况:

a=(a)
b=(a,)
print(a)
print(b)
运行结果:
a
(a,)

  在python里,括号在大所属情况下是可以忽略的,仅当元组作为常量穿个函数调用和元组在python2中print语句中列出时才必不可少。对于初学者可能对概念模糊不清,所以建议当前还是使用括号更好。

  如果想要操作元组,可以将其转化为俩表对象进行操作,然后再转化为元组,在进行排序的操作时可以使用sorted函数来完成,此函数接受任何序列对象。

  列表解析可以用于元组转换,列表解析甚至可以用在某些并非实际存储的序列之上,任何遍历对象都可以,包括逐行读取文件。

  注:元组也不是完全没有方法,index和count在元组中也是可以工作的。并且元组的不可变性只是本身,不包括它内部的元素,如果元组的内部是列表元素,那他依然可以进行修改列表。

其他python对象及类型

  篇幅有限简单介绍一下python的其他类型。

  None对象

  python特殊数据类型的唯一值,一般都起到一个空的占位作用。None不意味着无意义,None是某些内容,尽管是没有意义的意思,但是他是一个真正的对象,并且他有一块内存存放,python给定一个内置的名称。他还是函数的返回值。

  bool类型

  当明确地用在真值测试,真假就是1和0.交互模式下进行布尔测试结果也是打印成Ture与False。python内置函数bool()用于测试对象的真假。

  type对象

  即使是类型本身在python中也是有对象的。

print(type(type))
运行结果:
<class type>

  python还定义了isinstance来作为类型判断内置函数。

  :最后一点复合对象指向自身的引用,成为循环,python在对象中检测到循环就会打印成[...]而不会陷入无限的循环。

l=[1,2,3]
l.append(l)
print(l)
运行结果:
[1, 2, 3, [...]]

  除了这些核心对象以外,还有函数,模块和类的内核心数据类型,在之后的学习过程中,一一分享给大家。

列表、字典、元组进阶