Python 3 基本语法(二)容器


Python中的容器是异常好用且异常有用的结构。这节主要介绍列表(list),元组(tuple),字典(dict)和集合(set)。这些结构和其他语言中的类似结构并无本质不同,来看例子了解下使用:

1.列表(list)

a = [1, 2, 3, 4]
b = [1]
c = [1]
d = b
e = [1, "Hello world!", c, False]
print(id(b), id(c))                 # (194100040L, 194100552L)
print(id(b), id(d))                 # (194100040L, 194100040L)
print(b == c)                       # True
f = list("abcd")
print(f)                            # ['a', 'b', 'c', 'd']
g = [0]*3 + [1]*4 + [2]*2	    # [0, 0, 0, 1, 1, 1, 1, 2, 2]

(1)和变量不同的是,即使用相同的语句赋值,列表的地址也是不同的,在这个例子中体现在 id ( b ) 和 id ( c )不相等,而内容相等。
(2)列表也可以用list()初始化,输入参数需要是一个可以遍历的结构,其中每一个元素会作为列表的一项。
(3)“*”操作符对于列表而言是复制(见g=····)

列表的基本操作有访问,增加,删除,和拼接:

a.pop()             # 把最后一个值4从列表中移除并作为pop的返回值
a.append(5)         # 末尾插入值,[1, 2, 3, 5]
a.index(2)          # 找到第一个2所在的位置,也就是1
a[2]                # 取下标,也就是位置在2的值,也就是第三个值3
a += [4, 3, 2]      # 拼接,[1, 2, 3, 5, 4, 3, 2]
a.insert(1, 0)      # 在下标为1处插入元素0,[1, 0, 2, 3, 5, 4, 3, 2]
a.remove(2)         # 移除第一个2,[1, 0, 3, 5, 4, 3, 2]
a.reverse()         # 倒序,a变为[2, 3, 4, 5, 3, 0, 1]
a[3] = 9            # 指定下标处赋值,[2, 3, 4, 9, 3, 0, 1]
b = a[2:5]          # 取下标2开始到5之前的子序列,[4, 9, 3]
c = a[2:-2]         # 下标也可以倒着数,方便算不过来的人,[4, 9, 3]
d = a[2:]           # 取下标2开始到结尾的子序列,[4, 9, 3, 0, 1]
e = a[:5]           # 取开始到下标5之前的子序列,[2, 3, 4, 9, 3]
f = a[:]            # 取从开头到最后的整个子序列,相当于值拷贝,[2, 3, 4, 9, 3, 0, 1]
a[2:-2] = [1, 2, 3] # 赋值也可以按照一段来,[2, 3, 1, 2, 3, 0, 1]
g = a[::-1]	    # 也是倒序,通过slicing实现并赋值,效率略低于reverse()
a.sort()
print(a)            # 列表内排序,a变为[0, 1, 1, 2, 2, 3, 3]

因为列表是有顺序的,所以和顺序相关的操作是列表中最常见的,首先我们来打乱一个列表的顺序,然后再对这个列表排序:

import random
a = range(10)                 # 生成一个列表,从0开始+1递增到9
print(a)                       # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
random.shuffle(a)             # shuffle函数可以对可遍历且可变结构打乱顺序
print(a)                       # [4, 3, 8, 9, 0, 6, 2, 7, 5, 1]
b = sorted(a)               
print(b)                       # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
c = sorted(a, reverse=True)
print(c)                       # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

注:
(1)range()函数:If you do need to iterate over a sequence of numbers, the built-in function range() comes in handy. It generates arithmetic progressions(如果你需要遍历一个数字序列,可以是使用python中内建的函数range())

(2)shuffle() 函数:将序列的所有元素随机排序。注意:shuffle()是不能直接访问的,需要导入 random 模块,然后通过 random 静态对象调用该方法。

(3)sorted函数:需要对List、Dict进行排序,sorted(iterable, cmp=None, key=None, reverse=False)
iterable:是可迭代类型;
cmp:用于比较的函数,比较什么由key决定;
key:用列表元素的某个属性或函数进行作为关键字,有默认值,迭代集合中的一项;
reverse:排序规则. reverse = True 降序 或者 reverse = False 升序,有默认值。

2.元组(tuple)

元组和列表有很多相似的地方,最大的区别在于不可变,还有如果初始化只包含一个元素的tuple和列表不一样,因为语法必须明确,所以必须在元素后加上逗号。另外直接用逗号分隔多个元素赋值默认是个tuple,这在函数多返回值的时候很好用:

a = (1, 2)
b = tuple(['3', 4]) # 也可以从列表初始化
c = (5,)
print(c)            # (5,)
d = (6)
print(d)            # 6
e = 3, 4, 5
print(e)            # (3, 4, 5)

3.集合(dict)

集合是一种很有用的数学操作,比如列表去重,或是理清两组数据之间的关系,集合的操作符和位操作符有交集,注意不要弄混:

A = set([1, 2, 3, 4])
B = {3, 4, 5, 6}
C = set([1, 1, 2, 2, 2, 3, 3, 3, 3])
print(C)        # 集合的去重效果,set([1, 2, 3])
print(A | B)    # 求并集,set([1, 2, 3, 4, 5, 6])
print(A & B)    # 求交集,set([3, 4])
print(A - B)    # 求差集,属于A但不属于B的,set([1, 2])
print(B - A)    # 求差集,属于B但不属于A的,set([5, 6])
print(A ^ B)    # 求对称差集,相当于(A-B)|(B-A),set([1, 2, 5, 6])

4.字典(dict)

字典是一种非常常见的“键-值”(key-value)映射结构,键无重复,一个键不能对应多个值,不过多个键可以指向一个值。还是通过例子来了解,构建一个名字->年龄的字典,并执行一些常见操作:

a = {'Tom': 8, 'Jerry': 7}
print(a['Tom'])             # 8
b = dict(Tom=8, Jerry=7)    # 一种字符串作为键更方便的初始化方式
print(b['Tom'])             # 8
if 'Jerry' in a:            # 判断'Jerry'是否在keys里面
    print(a['Jerry'])        # 7
print(a.get('Spike'))       # None,通过get获得值,即使键不存在也不会报异常
a['Spike'] = 10
a['Tyke'] = 3
a.update({'Tuffy': 2, 'Mammy Two Shoes': 42})
print(a.values())   # dict_values([8, 2, 3, 7, 10, 42])
print(a.pop('Mammy Two Shoes'))     # 移除'Mammy Two Shoes'的键值对,并返回42
print(a.keys())     # dict_keys(['Tom', 'Tuffy', 'Tyke', 'Jerry', 'Spike']) 

注意到初始化字典和集合很像,的确如此,集合就像是没有值只有键的字典。既然有了人名到年龄的映射,也许你立马想到是否可以给字典排序?在Python3.6之前,这个问题是错误的,字典是一种映射关系,没有顺序。当然了,如果要把(键, 值)的这种对进行排序,是没有问题的,前提是先把字典转化成可排序的结构,items()或者iteritems()可以做到这件事,接上段代码继续:

b = a.items()
print(b)  # [('Tuffy', 2), ('Spike', 10), ('Tom', 8), ('Tyke', 3), ('Jerry', 7)]
from operator import itemgetter
c = sorted(a.items(), key=itemgetter(1))
print(c)  # [('Tuffy', 2), ('Tyke', 3), ('Jerry', 7), ('Tom', 8), ('Spike', 10)]
d = sorted(a.iteritems(), key=itemgetter(1))
print(d)  # [('Tuffy', 2), ('Tyke', 3), ('Jerry', 7), ('Tom', 8), ('Spike', 10)]
e = sorted(a)
print(e)  # 只对键排序,['Jerry', 'Spike', 'Tom', 'Tuffy', 'Tyke']

items()可以把字典中的键值对转化成一个列表,其中每个元素是一个tuple,tuple的第一个元素是键,第二个元素是值。变量c是按照值排序,所以需要一个操作符itemgetter,去位置为1的元素作为排序参考,如果直接对字典排序,则其实相当于只是对键排序。字典被当作一个普通的可遍历结构使用时,都相当于遍历字典的键。如果觉得字典没有顺序不方便,可以考虑使用OrderedDict,使用方式如下:

from collections import OrderedDict
a = {1: 2, 3: 4, 5: 6, 7: 8, 9: 10}
b = OrderedDict({1: 2, 3: 4, 5: 6, 7: 8, 9: 10})
print(a)    # {1: 2, 3: 4, 9: 10, 5: 6, 7: 8}
print(b)    # OrderedDict([(1, 2), (3, 4), (9, 10), (5, 6), (7, 8)])

这样初始化时的顺序就保留了,除了有序的特性以外,用法上和字典没有区别。2016年9月,Guido宣布在Python3.6中,字典将默认有序,这样就不用纠结了。另外需要注意的一点是字典是通过哈希表实现的,所以键必须是可哈希的, list不能被哈希,所以也不能作为字典的键,而tuple就可以。

因为上上段代码中用到了iteritems(),所以这里顺带提一下迭代器(iterator),迭代器相当于一个函数,每次调用都返回下一个元素,从遍历的角度来看就和列表没有区别了。iteritems()就是一个迭代器,所以效果一样,区别是迭代器占用更少内存,因为不需要一上来就生成整个列表。一般来说,如果只需要遍历一次,用迭代器是更好的选择,若是要多次频繁从一个可遍历结构中取值,且内存够,则直接生成整个列表会更好。当然,用迭代器生成一个完整列表并不麻烦,所以有个趋势是把迭代器作为默认的可遍历方式,比如前面我们使用过用来生成等差数列列表的range(),在Python2中对应的迭代器形式是xrange()。在Python3中,range()就不再产生一个列表了,而是作为迭代器,xrange()直接没了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值