python中内置的数据类型有列表(list)元组(tuple)字典(directory)。
1 list
list是一种可变的有序的集合。来看一个list实例:
#第一种方法: >>> name=['liming','xiaohong',] >>> name ['liming', 'xiaohong'] #第二种方法: >>> age=list([18,17,]) >>> age [18, 17]
list有许多功能:
>>> name ['liming', 'xiaohong'] >>> len(name) 2 >>> name.__len__() 2
>>> name ['liming', 'xiaohong', 'xiaoqiang'] >>> name[2] 'xiaoqiang'
>>> name ['liming', 'xiaohong', 'xiaoqiang'] >>> name.index('xiaohong') 1 #如果没有该元素,则会报错 >>> name.index('xiao') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 'xiao' is not in list
>>> name ['liming', 'xiaohong', 'xiaoqiang'] >>> name.append('xiaohuang') >>> name ['liming', 'xiaohong', 'xiaoqiang', 'xiaohuang']
>>> name ['liming', 'xiaohong', 'xiaoqiang'] >>> name.insert(1,'yefan') >>> name ['liming', 'yefan', 'xiaohong', 'xiaoqiang']
>>> name ['liming', 'yefan', 'xiaohong'] >>> result=name.pop() #将最后一个元素赋值给result >>> name ['liming', 'yefan'] >>> result 'xiaohong'
>>> name ['liming', 'yefan', 'xiaoqiang'] >>> name.pop(1) 'yefan' >>> name ['liming', 'xiaoqiang']
>>> name ['liming', 'yefan', 'xiaoqiang'] >>> name[1]='xiaohong' >>> name ['liming', 'xiaohong', 'xiaoqiang']
>>> name ['liming', 'xiaohong', 'xiaoqiang'] >>> name.extend(['yefan','heihuang',]) >>> name ['liming', 'xiaohong', 'xiaoqiang', 'yefan', 'heihuang']
>>> name ['liming', 'xiaohong', 'xiaoqiang', 'yefan', 'heihuang'] >>> name.reverse() >>> name ['heihuang', 'yefan', 'xiaoqiang', 'xiaohong', 'liming']
另外,list元素也可以是另一个list(字典也可以):
>>> name=['liming', 'xiaohong', 'xiaoqiang'] >>> age [18, 17] >>> name.append(age) >>> name ['liming', 'xiaohong', 'xiaoqiang', [18, 17]]
再来看list中一个让我刚学习时比较纠结的例子:
>>> n=[1] >>> l=n >>> l [1] >>> n=[4] >>> l [1] #上例中n变了,l没有变
>>> n=[1,2] >>> g=n >>> g [1, 2] >>> n[1]=3 >>> g [1, 3]
#在这里,n变了,g也跟着变了!!!
靠!这是为什么呢?欲知原因,请看--我的另一个博文 python基础之赋值/深copy/浅copy
当我们想要创建一个比较繁琐的list的时候,可能会用到循环,比如,我们要创建list为:[1,4,9,16,25……100]时。可能就会这样写:
l=[] for i in range(1,11): a=i*i l.append(a) print(l)
是不是感觉很麻烦,在python中,我们其实可以用一行代码来实现这个list,这里就要用到列表生成式了:
列表生成式:
>>> [i*i for i in range(1,11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
说一下格式:元素(上例中为i*i)+空格+生成元素的表达式(这样说其实并不准确,但我感觉墨水较少,实在是无法准确的形容。上例中为:for i in range(1,11))
列表生成式也可以帮助我们实现一些更为复杂的list:
#可以有两层循环 print([m+n for m in range(3) for n in range(3)]) [0, 1, 2, 1, 2, 3, 2, 3, 4] print([m+n for m in 'abc' for n in 'abc']) ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc']
#for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
#将格式化和列表生成式相结合 print(['%s%s' % (i,i) for i in range(1,11)]) ['11', '22', '33', '44', '55', '66', '77', '88', '99', '1010']
事实上,不仅可以有两层循环,三层或者更多层也是可以的。
2 tuple
是一种另类的list,但是他的功能相较于list要少,因为tuple不支持修改,也就是不支持append,pop,extend,insert……
定义一个tuple:
#第一种方法 >>> age=(1,3) >>> age (1, 3) #第二种方法 >>> age=tuple((1,4,)) >>> age (1, 4)
如果要定义一个空的tuple,可以写成()
:
>>> age=() >>> age ()
但是,要定义一个只有1个元素的tuple,如果你这么定义:
>>> age=(1) >>> age 1 >>> type(age) <class 'int'>
定义的不是tuple,是1
这个数!这是因为括号()
既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1
。
所以一般定义只有一个元素的tuple时,要加个逗号:
>>> age=(1,) >>> age (1,)
实际上tuple也是可变的,前文中所说的不可变指的是tuple元素不可变,但是tuple中的元素的元素是可以改变的。
>>> info=(['liming','14',],['xiaohong','13',]) >>> info (['liming', '14'], ['xiaohong', '13']) >>> info[1][1]=12 >>> info (['liming', '14'], ['xiaohong', 12])
在这个例子中改变的不是tuple的元素,而是list的元素。
3 directory
字典是无序的由键值对组成的集合,具有极快的查找速度。元素可以是list tuple directory
为什么说dict具有极快的查找速度?现在来看一个小程序:
name=['liming','xiaohong','xiaoqiang',] score=[88,77,66,] in_name=input('Please input your name:') in_name.strip() index_name=name.index(in_name) score_of_name=score[index_name] print('Your score is:%s'%(score_of_name))
当列表的元素越多,输入名字后匹配到的时间就越长。因为我们需要遍历整个list,然后匹配到相应的name以及score。
如果用dict实现,只需要一个“名字”-“成绩”的对照表,这个对照表是按照一定的计算方法存放的,什么计算方法呢?打个比方,我们可以根据名字的首字母在字母表中的顺序,首字母相同的名字再根据第二字母在字母表中的顺序排序,以此类推……。这样我们查找名字时就会方便快捷很多。直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。以上只是打比方,实际上dict可能是根据hash来进行排序计算,有兴趣的同学可以搜索一下。
定义一个字典:
>>> info={'liming':16,'xiaohong':12} >>> info {'xiaohong': 12, 'liming': 16} #格式是一个唯一的键对应一个值。
但是,当第二次定义一个键时,会出现这种情况:
>>> info {'xiaohong': 12, 'liming': 16} >>> info={'liming':16,'xiaohong':12,'liming':12} >>> info {'xiaohong': 12, 'liming': 12}
也就是第二个相同的键会覆盖掉第一个相同的键
对某个键的值进行修改:
>>> d['liming'] 88 >>> d {'xiaohong': 77, 'liming': 88} >>> d['liming'] 88 >>> d['liming']=99 >>> d {'xiaohong': 77, 'liming': 99}
但是如果当这个键不存在时,就会报错:
>>> d {'xiaohong': 77, 'liming': 99} >>> d['xiao'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'xiao' #我们可以用in或者字典所提供的get功能来判断键是否存在 #in >>> d {'xiaohong': 77, 'liming': 99} >>> 'xiaohong' in d True #注意仅仅是找键,而不是找值: >>> 77 in d False #get >>> d.get('xiaohong') 77 #当不存在时,可以定义返回值,默认返回值是None >>> d.get('xiao') >>> result=d.get('xiao',0) >>> result 0
和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key的增加而变慢;
- 需要占用大量的内存,内存浪费多。
而list相反:
- 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:
>>> score [88, 77, 66] >>> name ['liming', 'xiaohong', 'xiaoqiang'] >>> d={name:score,'liming':99} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list'
dict的功能:
#当[]中的键不存在时,即为添加 >>> dic={'liming':15} >>> dic['xiaohong']=20 >>> dic {'liming': 15, 'xiaohong': 20} #当[]内的键存在时,即为修改 >>> dic {'liming': 15, 'xiaohong': 20} >>> dic['liming']=20 >>> dic {'liming': 20, 'xiaohong': 20}
>>> d {'xiaohong': 77, 'liming': 99} >>> d.clear() >>> d {}
d {'xiaohong': 77, 'liming': 99} >>> d.get('xiaohong') 77 >>> d.get('xiao') >>> result=d.get('xiao',0) >>> result 0
>>> d {'xiaohong': 77, 'liming': 99} >>> d.keys() dict_keys(['xiaohong', 'liming'])
>>> d {'xiaohong': 77, 'liming': 99} >>> d.values() dict_values([77, 99])
>>> d {'xiaohong': 88, 'liming': 99} >>> d.update({'xiaohong':77}) >>> d {'xiaohong': 77, 'liming': 99} >>> d['xiaohong']=66 >>> d {'xiaohong': 66, 'liming': 99}
>>> d {'xiaohong': 66, 'liming': 99} >>> d.pop('xiaohong') 66 >>> d {'liming': 99}
4 set集合
set集合类似于dict,查找速度十分快,无序,不重复。但是,set仅仅是key的集合,并没有value。
定义set
>>> a=set([1,1,2,3,4,4,5,]) >>> a {1, 2, 3, 4, 5} #重复的会被过滤
set的功能:
>>> a {1, 2, 3, 4, 5} >>> a.add(7) >>> a {1, 2, 3, 4, 5, 7}
>>> a {1, 2, 3, 4, 5, 7} >>> a.clear() >>> a set()
#有两种取差集 #一种是普通差集,一种是对称差集。 #先看普通差集: >>> a {1, 2, 3} >>> b {2, 3, 4} >>> a.difference(b) {1} #a并没有改变 >>> a {1, 2, 3} #我们可以将a.difference(b)赋值给一个变量 >>> ret=a.difference(b) >>> ret {1} #有另一种方法可以直接将差集赋值给a >>> a.difference_update(b) >>> a {1} #对称差集就是a.difference(b) 和b.difference(a)合并 >>> a {1, 2, 3} >>> b {2, 3, 4} >>> a.symmetric_difference(b) {1, 4}
>>> a {1, 2, 3} >>> b {2, 3, 4} >>> a.intersection(b) {2, 3} #更新自身的取交集 >>> a {1, 2, 3} >>> b {2, 3, 4} >>> a.intersection_update(b) >>> a {2, 3}
>>> b {3, 4} >>> ret = b.pop() >>> ret 3 >>> b {4}