一.关于python序列的简介。
python里面的序列大部分都可以执行,索引,切片,加,乘,检查长度,以及检查某个成员是否存在,甚至还可以找出这个序列中最小的元素和最大的元素,并且序列都是可迭代的。
解释下个人理解的迭代,迭代(iteration),序列中的迭代就是对序列中的每个元素重复执行某些操作/
具体的迭代方式后面会说到。
下面就说说python序列的共有特点。
1.索引
一个序列中,所有的元素都有自己的编号,这个编号是从0开始的,这个编号就是所谓的索引,这些元素可以通过索引来依次访问。下面就拿字符串类型举个例子,字符串在python中也是序列的一种。
test = "suhaozhi"
print test[0] (打印序列中的第一个元素,也就是打印字符串的第一个字符。)
s
根据上面的示例就可以看出,python中的字符串就是由字符组成的序列,索引0指向了序列中的第一个元素,在这个例子中就是s。
python中几乎所有的序列都可以使用这种索引,如果索引是负数时,python会从右边,也就是最后一个元素开始计数,如果想直接取序列中最后一个元素的话,可以直接使用-1。
test = "suhaozhi"
print test[-1]
i
2.分片
如果说索引一次只能访问序列中的一个元素,那么分片就可以通过索引一次访问序列中的一段(一个范围的)元素。
分片操作通过冒号隔开两个索引来实现。
假如说现在定义了一个变量,这个变量里是个字符串,字符串的内容是www.baidu.com,现在要通过分片取出前面的三个字符‘www’,操作方法如下。
url = 'www.baidu.com'
print url[0:3]
www
第一个索引“0”是要提取的第一个元素编号(开头)而最后一个索引“3”责是分片之后!剩余部分!的第一个元素号。
分片操作的视线是需要两个索引作为边界,第1个索引的元素是包含在分片内的,第二个不包含在分片内。
那么假如说这个字符串的长度未知,我只想取最后三个字符,该如何操作呢?
url = 'www.baidu.com'
print url[-3:]
com
如果分片获取到的部分需要包括结尾的元素,那么后面的索引就需要为空。
这种方法也可以用在开始的元素上。
url = 'www.baidu.com'
print url[:3]
www
3.分片之步长。
在对序列进行分片的时候,开始和结束都需要指定,而另一个参数“步长”,这个参数是隐藏的,默认值是1,我们的分片操作就是按照步长来逐个遍历序列中的元素,然后返回开始和结束点之间所有的元素。
比如说以下面这个列表为例:
我们对下面这个列表做一个分片操作。
l1 = [1,2,3,4,5,6,7,8,9,10]
现在要取这个列表中的1到9。
print l1[0:9:1]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
其中0:9:1前面的0:9前面已经解释过了,是开始和结束的位置,最后一个1就是步长参数,不管这个参数写不写,默认就是1。
如果步长被设置为比1大的数,那么就会跳过某些元素,比如说将步长设置为2,就会出现以下效果。
l1 = [1,2,3,4,5,6,7,8,9,10]
print l1[0:9:2]
[1, 3, 5, 7, 9]
每取一个元素都会跳过一个元素。
补充一点!:步长不可以为0,但是可以为负数!如果步长设置为负数,那么就会从右向左开始取元素。
l1 = [1,2,3,4,5,6,7,8,9,10]
print l1[::-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
如果说开始的元素包括在结果之中,结束的元素,不能在分片之内,当使用一个负数作为步长的时候,开始的索引节点必须大于结束的索引!!!!对于一个正数的步长,python会从序列的头部(左)向右开始提取元素,但是对于负数的步长,则是从序列的尾部(右)开始向左提取元素!!所以说,如果要使用负数作为步长,那么开始的索引要大于结束的索引。
4.序列之间的相加。
相同类型的序列之间是可以合并拼接起来的,只要通过+加号就可以做到。
比如说现在拼接两个列表。
print [1,2,3] + [4,5,6]
[1, 2, 3, 4, 5, 6]
这样,两个相同类型的序列就拼接起来了。
字符串也是如此。
print "hamasaki" + "ayumi"
hamasakiayumi
不过需要注意,不同类型的序列是不可以拼接在一起的,比如说列表和字符串,虽然说都是序列,但是它们属于不同的类型!!!
5.关于序列与乘法。
用数字去乘以一个序列,会生成一个新的序列,在新的序列中,原来的序列会被重复n次。
比如说:
print "suhaozhi" * 5
suhaozhisuhaozhisuhaozhisuhaozhisuhaozhi
suhaozhi被重复了5遍。
print '*' * 50
**************************************************
*号被重复了50遍。
这事关于字符串的示范,列表也是一样。
print [1,2,3] * 10
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
那么这种蛋疼的序列乘法永在什么位置呢?
个人理解,这种序列乘法可以用来占用序列里面元素的空间,也就是初始化,创建一个空列表[]可以用中括号来表示,但是这个列表中什么都没有,假如说这时需要创建一个占用是个元素的空间,但是这个列表中不能有任何内容(每个元素必须是空值),这时候序列乘法就可以发挥作用了。
每个元素都需要为空,就意味着列表不可以有任何元素,这种情况就需要使用None了,None是python的内建值,就是什么都没有的意思,因此,如果想要初始化一个长度为10的列表,但是这个列表中什么都不可以放,就可以使用下面的例子来实现。
test = [None] * 10
print test
[None, None, None, None, None, None, None, None, None, None]
6.检查某个成员在序列中是否存在。
检查一个元素是否在指定的序列中,可以使用in来进行检测(关于in运算符,在前面的运算符介绍中讲过了,可以查看前面的文章~),当要检查的元素存在于这个序列中,责返回True否则返回False,下面是使用in来检查元素是否存在于序列的例子。
比如说检查linux/unix文件的权限(rwx)。
permissions = ''rw"
print 'w' in permissions
True
在说一个通俗易懂的例子,检查一个用户的名字是否在列表上。
l1 = ['linhaifeng','suhaozhi','andy'] print "suhaozhi" in l1
True
名字存在于列表中就返回了True。接着在查一个列表中没有的。
l1 = ['linhaifeng','suhaozhi','andy'] print "ayumi"
没有的元素,就直接返回了一个False
7.计算序列长度,取出序列中的最大元素和最小元素。
python中内置了len(),min(),max()这三个特别有用的函数,其中len函数可以返回序列中元素的数量,也就是这个序列的长度,min可以返回这个序列中最小的元素,max则可以返回这个序列中最大的元素。
下面演示下这三个常用函数的用法。
Username = ["linhaifeng","suhaozhi","andy","tony"]
现在有个列表,需要计算这个列表中有多少个元素。
print len(Username)
4
最后返回的结果是4,就说明这个列表中有4个元素。
计算序列长度的这个函数还可以永在字符串上,因为字符串也是序列的一种啊。
print len("Hello")
5
返回的结果是5,就说明这个字符串中有5个字符。
len说完了,在简单演示min和max函数。
test = [1,2,3,4,5,6] min(test)
1
查找test这个列表中最小的元素,这个最小的元素就是1。
再试试max函数。
test = [1,2,3,4,5,6] max(test)
6
min和max函数,一般情况下,用来查找序列中的数字,如果是英文字符串的话,是按照首字母排序去进行查找的。
补充!:在这补充一点,min和max函数不只可以用于单个序列中找出最大值和最小值,这两个函数可以同时接收多个参数,在多个参数中找出最大值和最小值。
print min(1,2,3,4,5,6)
1
print max(1,2,3,4,5,6)
6
二.细说python列表(list)。
基本序列所具有的功能,列表都具备,索引,分片,连接,乘法列表都可以,和字符串不同的是,列表是可以修改的,列表支持,添加元素,插入元素, 删除元素,甚至还可以分片赋值,然而前面说的那些列表支持的功能,字符串都不能做。
1.修改列表中的元素。
想要修改列表中的某个元素,需要借助元素的索引才可以去修改,想去修改一个元素,必须明确这个元素的位置,索引。
test_list = ["aaa","bbb","ccc"]
假如说,现在要给上面那个列表中的第0个元素“aaa”替换为“suhaozhi”,下面就是操作方法。
test_list[0] = "suhaozhi" print test_list
['suhaozhi', 'bbb', 'ccc']
这个列表中的第0个元素就被成功修改为“suhaozhi”了。
2.列表之分片赋值。
个人觉得列表的分片赋值功能做的特别的屌,分片赋值就是把修改列表中元素和分片联合起来使用。
前面介绍了,字符串虽然也是序列的一种,但是字符串这种序列是不支持修改的,那怎么让这种序列变得可以修改呢?这个时候就可以用到列表的分片赋值功能,其实分片赋值就是通过索引分片,然后在通过索引去修改列表中的元素,下面来做个演示~~
name = "perl"
首先我们定义了一个变量,这个变量中存的是个字符串“perl”,现在要对这个字符串序列的最后三个字母进行修改,把这个字符串变成python,操作方法如下。
name = list("perl")
#首先使用list()工厂函数,将perl这个字符串强制转换成列表的格式,转换后,我们先在屏幕上输出下这个转换后的列表看看。
print name
['p', 'e', 'r', 'l']
转换成功后,通过之前说的分片和索引,去修改列表中的元素。
name[1:] = list("ython") print name
#然后我们来打印一下这个列表看下。
['p', 'y', 't', 'h', 'o', 'n']
#列表中的元素已经替换完成了,接下来需要做的就是,使用join()方法,把列表中的每个元素合并为一个字符串。
print "".join(name)
python
3.删除一个元素。
从列表中删除一个元素,可以使用del语句来实现。
test_list = ["aaa","bbb","ccc"]
现在需要删除这个列表中的第二个元素(从第0个开始数)。
del test_list[2] print test_list
['aaa', 'bbb']
第二个元素“ccc”就被删掉了。
关于del语句~在这里需要特别补充一下!!
del语句不只可以删除列表中的元素,甚至还可以删除其他元素,还可以删除变量!!
4.python中列表中常用方法介绍。
在介绍列表的常用方法之前,先说一个关于函数和方法的概念,方法这个东西确实和函数看起来有点类似,但是是不一样的,但是“方法”是需要“类”去调用的,这个“类”可能是数字,也可能是字符串,列表,活着其他对象,但是函数是可以直接使用的,这就是它们的不同,举个例子。
当函数被加载到内存后,直接 函数名后面加上括号就可以使用了,就像这样 func_name()。
而方法呢是需要通过对象去调用的,比如 对象名.方法(参数)。
下面开始正式介绍列表的常用方法啦。
4.1 append用于在列表的尾部追加一个新的元素。
l1= [1,2,3]
#在列表尾部添加一个新的元素4 l1.append(4)
print test
[1, 2, 3, 4]
注意!!!在这里有个特别注意事项,就是append方法并不是简单的返回一个修改过的新列表,而逝把原来的旧列表直接进行操作!!!!
4.2 count 统计一个元素在列表中出现的次数。
列表中的元素是可以重复的,count方法可以统计一个元素在这个列表里重复出现了多少次。
下面是例子。
test = ["suhaozhi","linhaifeng","linhaifeng"]
这个列表中有一个“suhaozhi”两个“linhaifeng”,用count方法就可以找出这个列表中有多少个linhaifeng。
print test.count("linhaifeng")
2
返回的数值是2,就说明有2个。
4.3 extend 拓展列表,可以一次性在列表的末尾追加n个值,还可以用一个新的列表去拓展原有的列表。
lia= [1,2,3] lib = [4,5,6]
现在有lia和lib两个列表,现在要将lib列表中的所有元素全部添加到lia的尾部。
lia.extend(lib)
添加完成后,我们再来看看lia列表。
print lia
[1, 2, 3, 4, 5, 6]
关于extend方法有个很重要的知识点需要补充!!!!!
还记得之前说的使用+加号去连接两个相同的序列吗?[1,2,3] + [4,5,6] extend方法和这种拼接的加号看起来作用很相像,但是本质上完全不同!!!!!extend方法会修改原有的列表!!!而加号拼接则不回修改原列表,会返回一个全新的列表!!!!这两个地方千万不要弄混!!
4.4 index 返回指定元素的索引。
index方法用于从列表中找出第一个匹配的元素的索引位置。
lia = [1,2,3,"suhaozhi","andy","suhaozhi"]
print lia.index("suhaozhi")
3
在搜索suhaozhi的时候,就会发现它在索引为3号的位置,这个列表中有两个“suhaozhi”但是index方法会从列表的左侧开始找,如果找到了,直接返回结果,不在向下匹配了。
如果找不到指定的元素,那么index方法就会抛出一个异常。
4.5 insert 将指定的对象按照指定的位置插入到列表中。
li1 = [1,3,5,7,9]
这有个列表,现在想把字符串“two”,插入到索引为1的位置,也就是1和3的中间。
li1.insert(1,"two")
print li1
[1, 'two', 3, 5, 7, 9]
4.6 pop 弹出,从列表中弹出一个元素,默认弹出最后一个,但是可以通过索引来指定具体弹出哪个元素。
在这解释下弹出是什么意思,弹出就是从列表中删除一个元素,在这个元素被删除时,被删除的这个元素会作为执行这个方法的返回值。
下面是关于pop方法的操作:
li1 = [1,2,3,4] l11.pop() print li1
[1, 2, 3]
这个列表最末尾的元素4被弹出了。
接下来我们手动指定弹出第0个元素。
l1 = [1,2,3] l1.pop(0) print l1
1
[2, 3]
第0个元素就从列表中被弹出了。
这个pop方法在什么情况下会使用呢?
在实现后进先出(LIFO)队列的时候,pop方法就发挥出它的用处了。
在这介绍下什么是LIFO后进先出队列,后进先出队列,也被称为,“堆栈”,就好像堆盘子,在拿盘子的时候,一次只能从顶部拿一个盘子,也就是说最后放的盘子,会被最先拿走,同样,最后被放入队列,最先从队列中移除,这就是堆栈,LIFO后进先出队列。
接下来我们验证下pop是否具有弹出的功能,能否实现“堆栈”。
l1 = [1,2,3] l1.append(l1.pop()) print l1
[1, 2, 3]
li1.pop()先被执行,最末尾的元素3被弹出,被弹出后作为返回值被li1.append()方法又一次放回到了li1列表的尾部,这样就实现了“堆栈”,以后在需要后进先出队列的时候,就可以使用列表的pop方法来实现。
4.7 remove移除,从列表中移除一个元素,但是没有返回值~
remove方法可以用来移除列表中第一个匹配到的元素。
l1 = ['linhaifeng','suhaozhi','linhaifeng'] l1.remove('linhaifeng')
['suhaozhi', 'linhaifeng']
从上面的例子就可以看到,只有第一次被匹配到的元素被删除了。
当使用remove删除一个不存在的元素,则会直接抛出异常!
remove和pop最大的区别就是,remove删除一个元素是没有任何返回值的。
4.8 reverse 倒序,将列表中存放的元素,按照和原来相反的顺序进行排序。
test = [1,2,3] test.reverse()
[3, 2, 1]
特别注意!!!如果需要做反向的迭代操作,有个专门做反向迭代的函数,也叫reverse()这个reverse函数和列表中带的reverse方法是有区别的,如果需要做反向迭代操作,强烈推荐reverse函数,这个函数返回的不是一个列表,而是一个迭代器(iterator)对象,直接放到循环中进行反向迭代。
(经过测试,直接使用list()函数强制把返回的迭代器转换成列表也是可以的。)
4.9 sort 排序。
使列表中的元素按照一定顺序去排列,sort方法也是直接就该列表本身的。
test = [2,1,3] test.sort()
[1, 2, 3]
关于sort方法也需要额外的补充一下,如果不想对原列表进行修改,想生成一个排序后的新的副本,那么sorted()函数是最好的选择,sorted()函数会将排序后的列表生成一个新的列表。
sorted函数虽然可以针对各种序列进行排序,但是返回值却永远都是以列表的形式
print sorted("dcba")
['a', 'b', 'c', 'd']
#python中列表中元素的排序方式还可以自己指定,本篇文章主要是说明,列表,元组,字典之类的使用方法,关于排序后面会单独有一篇文章做介绍。
三.python元组(tuple)的使用。
元组合列表非常类似,但是它们最大的区别就是元组是不可变的,不能做任何修改,生成元组的方法特别简单,只要使用逗号(,)分隔了一些值,就自动创建了元组。
t1 = 1,2,3,4 print type(t1)
<type 'tuple'>
print t1
(1, 2, 3, 4)
元组也支持分片,方法和列表一模一样,这个就不多介绍啦。
元组分片后还是元组。
既然列表比元组的功能还多,那么要元组有毛用?
上网找了好多资料,终于知道元组为什么不可替代了。
元组可以在创建字典时作为key使用,列表却不行。
四.python字符串的基本使用(str)。
在本篇文章中,不对字符串格式化做介绍,只介绍关于字符串的一些常用方法,关于字符串格式化,后面会单独写一篇文章。
下面介绍一些比较常用的字符串方法(字符串的方法实在太多了,在这里说些常用的吧。)
1.find()在字符串中,查找想要找的子串。
它会返回子串从左数第一个位置的索引,如果没有找到对应的子串则会返回-1。
s1 = 'maybe you to'
print s1.find("you")
6
find方法不会返回布尔值,如果返回值是0,责说明了在第0位置的索引找到了子串。
补充一个find方法的用法,find方法还支持按字符串的指定范围查找子串。
比如说查找字符串y,如果不传任何参数的话,直接在maybe中就可以找到y。
s1 = 'maybe you to' print s1.find('y')
2
在第2个索引的位置,找到了y,然后就不在继续找了,接着我们指定下索引的范围让find从第6个索引开始找,找到第9个索引。
s1 = 'maybe you to'
print s1.find('y',6,9)
6
我们可以手动指定find方法的查找范围,从哪个索引的字符串开始,从哪个索引的字符串结束。
‘y’是要从字符串中查找的子串,6指从第6个索引开始,9是指从第9个索引开始结束。
2.join 拼接,是字符串中非常非常重要和常用的方法。
主要的功能是用来拼接序列中的元素,让序列中的元素使用指定的字符串连接起来。
注意!join方法只可以拼接字符串!!!其他的序列是无法拼接的,数字也不行!!
l1 = ['1','2','3','4','5','6']
这个列表中所有的数字已经使用单引号转换成了字符串。
现在需要做的就是使用+-将l1列表里所有的元素连接成一个字符串。
print "+-".join(l1)
1+-2+-3+-4+-5+-6
3.lower小写,将字符串中所有的字符全部转换为小写。
如果想要做这种“不区分大小写”的功能的话,这个方法就派上用场了,无论大写小写,全部转换为小写。
在python中,是严格区分大小写的,假如想要在列表中查找一个元素是否存在,比如说在列表中找到字符串为“guilty“的元素,但是用户输入的是GUILTY,由于python会严格区分大小写,就会导致指定的元素找不到。
下面是关于大小写的测试代码。
name = "GUILTY"
test = ["suhaozhi","guilty"]
if name in test:
print "ok"
else:
print "not found!"
not found
列表中命名有guilty这个元素,因为大小写的问题,现在找不到。
接下来就使用lower方法,对字符串做个转换。
name = "GUILTY".lower()
test = ["suhaozhi","guilty"]
if name in test:
print "ok"
else:
print "not found!"
ok
这样,指定的元素就找到了。
print "GUILTY".lower()
guilty
在这里看到字符串成功的被转换成小写。
4.replace 替换,替换字符串中指定的子串。
这个方法,没有什么好说的,功能就是字符串替换,下面是例子。
s1 = "i have a pen"
print s1.replace("pen","apple")
i have a apple
5.split 拆分,也是特别重要和常用的一个字符串方法,将字符串按照指定的格式进行拆分,并且以列表的方式返回。
s1 = '1+-2+-3+-4+-5+-6+-7'
将上面的字符串以+-为分隔符拆分。
s1 = '1+-2+-3+-4+-5+-6+-7'
print s1.split('+-')
['1', '2', '3', '4', '5', '6', '7']
补充~在使用split做拆分的时候,如果不指定分隔符,默认责会使用空格,制表符,换行符作为分隔符。
split方法中,还可以指定最大的拆分次数,做多可以拆多少次,假如说,最多只拆分两次,可以在加个参数2
s1 = '1+-2+-3+-4+-5+-6+-7'
print s1.split('+-',2)
['1', '2', '3+-4+-5+-6+-7']
上面那个字符串被拆成了三个元素,前两个+-被当作拆分符拆了两次。
6.strip脱掉...去除字符串两侧的字符,一般情况下,经常用这个方法来去掉换行符和空格。
s1 = "+aaa+"
print s1.strip('+')
aaa
字符串两边的+加号被去掉了。
strip只能去掉字符串两边的多余字符,对字符串中间的字符不生效。
这个方法也很常用,用来去掉空格和换行符特别管用!!!!
五.python字典(dict)的基本使用方法。
当数字索引不好用的时候,就可以考虑使用字典啦。
字典是python中唯一的映射类型,字典中的值没有特殊的顺序,都是存储在特定的key下,key可以是数字,可以是字符串,也可以是元组。
下面是字典的创建和使用字典。
字典是由多个键值对组成的,每个key(键)和它的value(值)都是用:冒号分隔,每个键值对之间都使用逗号分隔,最外层使用大括号括起来{}。
下面是python字典的结构。
dict1 = {"k1":"v1","k2":"v2","k3":"v3"}
python字典的创建方法。
方法1:最常规的字典创建方式。
dict1 = {"k1":"v1","k2":"v2","k3":"v3"}
方法2:使用元组影射。
items = [('name','suhaozhi'),('age',22)]
d1 = dict(items)
print d1
{'age': 22, 'name': 'suhaozhi'}
方法3:通过关键字来创建字典。
d1 = dict(name = 'suhaozhi',age = 22)
print d1
{'age': 22, 'name': 'suhaozhi'}
创建空字典:
d1 = {}
d1 = dict()
1.字典的基本操作。
字典不属于序列,但是它的操作方法和序列很类似。
1.1查看字典有多少键值对。
如果想要查看一个字典里有多少键值对,使用len()函数就可以查到。
dict1 = {"k1":"v1","k2":"v2","k3":"v3"}
print len(dict1)
1.2获取字典中某个key对应的value。
print dict1['k1']
v1
注意!这种获取vlaue的方式不推荐,因为一旦找不到指定的key,程序又会抛出异常,推荐使用字典中的get方法去获取vlaue,get方法后面会介绍!!
1.3对字典中指定的key赋值。
dict1 = {"k1":"v1","k2":"v2","k3":"v3"}
dict1['k4'] = 'v4'
print dict1
{'k3': 'v3', 'k2': 'v2', 'k1': 'v1', 'k4': 'v4'}
1.4删除字典中指定的键值对。
要删除字典中的某个键值对,只需要指定键(key)就可以删除了。
dict1 = {"k1":"v1","k2":"v2","k3":"v3"}
del dict1["k1"]
print dict1
{'k3': 'v3', 'k2': 'v2'}
1.5检查字典中是否存在指定的key。
dict1 = {"k1":"v1","k2":"v2","k3":"v3"}
print 'k3' in dict1
True
2. 关于创建字典的一些注意事项。
key的类型,需要注意,字典的key可以是任意的不可变类型,可以是字符串,可以是浮点数,也可以是数字,也可以是元组,只要是不可变的类型都可以做字典的key。
字典的键值对是可以自动添加的,即使某个key在字典中并不存在,只要直接给key赋值,python就会去创建这个key(所以字典没有append方法就是因为这个原因)。
3.字典(dict)的常用方法。
3.1 clear清除,该方法可以清除字典中所有的项,无任何返回值。
dict1 = {"k1":"v1","k2":"v2","k3":"v3"}
dict1.clear()
print dict1
注意啦!!其实clear方法看起来很普通,清空了字典里所有的key和value,这些定义一个空字典也可以做到,但这并非真正的删除,clear可以做到真正意义上的删除!下面是示例。
第一种情况:
d1 = {}
#首先创建了一个空字典。
d2 = d1
#创建了一个d2变量,把内存地址指向d1
d1['k1'] = 'v1'
#给d1字典创建了一个键值对
print d2
{'k1': 'v1'}
#新创建的那个键值对在变量d2上也可以看到,这是因为,d1和d2使用了指向了同一个内存地址,不相信的话,可以使用id()函数去查看!
d1 = {}
#从新给d1变量赋值了一个空字典,注意!!这并不是删除,而是改变了d1变量原来的内存地址!!!
d1的新内存地址指向了一个空字典。
print d2
{'k1': 'v1'}
#然而d2的内存地址没有像d1那样发生变化,指向的还是原来的那个位置,所以,之前的键值对并没有删除,还在内存空间中没有释放,如果想真正的删除,就需要使用clear方法。
下面是使用clear方法去清空字典,和上面那种所谓的“删除”做个比较。
d1 = {}
d2 = d1
d1['k1'] = 'v1'
print d2
{'k1': 'v1'}
d1.clear()
print d2
{}
所以说,clear才是真的清除。
3.2 copy 浅复制,返回一个具有相同键值对的新字典。
首先先举一个不使用copy方法,直接靠变量之间赋值实现所谓的“复制”!
d1 = {'k1':'v1','k2':'v2'}
d2 = d1
print d1
{'k2': 'v2', 'k1': 'v1'}
print d2
{'k2': 'v2', 'k1': 'v1'}
看起来像是通过变量间赋值的方式,实现了一个类似“复制”的效果,其实这并不是真正的复制,具体原因,看下面的操作就明白了。
接下来,我们给d1增加一个键值对。
d1['k3'] = 'v3'
虽然改变的是d1变量中的字典,但是!d2中的字典也会发生同样的改变!!
print d1
{'k3': 'v3', 'k2': 'v2', 'k1': 'v1'}
print d2
{'k3': 'v3', 'k2': 'v2', 'k1': 'v1'}
修改了d1,d2也发生了同样的改变,这是因为d1和d2同时指向了一个内存地址,这两个变量使用的是相同的内存空间,这一点是可以通过id函数看到的。
print id(d1)
4481913472
print id(d2)
4481913472
这两个变量使用的内存地址是一模一样的!!!
下面是copy方法的使用示例。
d1 = {'k1':'v1','k2':'v2'}
d2 = d1.copy()
#使用copy方法,去复制字典
d2['k3'] = 'v3'
#修改复制后的字典,给新字典增加一个键值对。
print d1
{'k2': 'v2', 'k1': 'v1'}
print d2
{'k3': 'v3', 'k2': 'v2', 'k1': 'v1'}
#从这可以看出,修改了新字典后,对新字典进行修改,完全没有影响到d1变量。
#这是因为d2现在是一个独立的个体,d1和d2复制后内容虽然一样,但是分别使用的是不同的内存空间,下面使用id函数去查看一下
print id(d1)
4537868928
print id(d2)
4538835584
注意!!字典中的copy方法只是浅拷贝,只会拷贝父级对象,如果字典中有子对象(字典中嵌套了字典,或者嵌套了列表,就是子对象。)
下面来测试一下。
d1 = {'k1':'v1','k2':'v2','k3':[1,2,3]}
d2 = d1.copy()
print d1
{'k3': [1, 2, 3], 'k2': 'v2', 'k1': 'v1'}
print d2
{'k3': [1, 2, 3], 'k2': 'v2', 'k1': 'v1'}
#k3这个key对应的值是一个列表,这个列表在字典中就是个子对象,现在在这个列表中追加一个元素。
d2['k3'].append(4)
#这时,我们查看一下d1和d2字典都发生了哪些变化。
print d1
{'k3': [1, 2, 3, 4], 'k2': 'v2', 'k1': 'v1'}
print d2
{'k3': [1, 2, 3, 4], 'k2': 'v2', 'k1': 'v1'}
#修改了一个字典中的子对象后,副本的子对象也发生了变化。
这说明了一个问题,就是copy方法只会复制字典中的父级对象,子对像其实并没有复制,而是两个字典中的key同时指定了同一个内存空间!!
如果想要使字典中的子对象也得到独立的复制,则可以使用copy模块中的deep copy(深度复制)。
想要做这种深度复制,需要导入一个copy模块中的deepcopy函数。
from copy import deepcopy
d1 = {'k1':'v1','k2':'v2','k3':[1,2,3]}
d2 = deepcopy(d1)
d2['k3'].append(4)
print d1
{'k3': [1, 2, 3], 'k2': 'v2', 'k1': 'v1'}
print d2
{'k3': [1, 2, 3, 4], 'k2': 'v2', 'k1': 'v1'}
3.3 fromkeys()使用指定的键,建立一个新的字典,并且给每个key赋予一个默认的value,如果不指定value,默认为None。
d1 = dict.fromkeys(['name','age'])
print d1
{'age': None, 'name': None}
我们还可以手动指定默认值。
d1 = dict.fromkeys(['name','age'],"aaa")
print d1
{'age': 'aaa', 'name': 'aaa'}
#每建立了一个键值对,值默认等于aaa。
3.4 get()用于访问字典key对应的值,d2['k3']和这种取值方式很类似,但是get这种方法在取值时,如果遇到了找不到的key,则不会抛出任何异常。
如果遇到了在字典中找不到的key,默认会返回None,我们还可以手动去指定get方法的返回值。
d1 = {'name':'suhaozhi','age':22}
print d1.get('name')
suhaozhi
d1 = {'name':'suhaozhi','age':22}
#接下来查找一个字典中不存在的key,看看会返回什么。
print d1.get('aaaa')
None
#当找不到指定的key时,默认会返回None,我们还可以手动指定返回值。
#当现在需要指定,去找一个不存在的key,如果找不到返回字符串null。
d1 = {'name':'suhaozhi','age':22}
print d1.get('aaaa','null')
null
3.5 has_key 检查key,检查字典中是否存在指定的key,也可以使用in去检测,这两个是一模一样的。
3.6 items 将字典所有的项,以列表的方式返回,列表中嵌套的是元组,每一个键值对都包含在同一个元组中。
d1 = {'name':'suhaozhi','age':22}
print d1.items()
[('age', 22), ('name', 'suhaozhi')]
3.7 iteritems 和items方法类似,但是iteritems方法返回的是个迭代器,不是列表。
如果需要做迭代操作的话,强烈推荐iteritems方法!因为它更高效!!!。
3.8 keys 返回一个字典中所有的key,以列表的形式返回。
d1 = {'name':'suhaozhi','age':22}
print d1.keys()
['age', 'name']
3.9 iteritems 和key类似,返回的也是一个字典中所有的key,以迭代器的方式返回。
3.10 pop 弹出,弹出字典中指定键值对,通过key来指定。
(之前在list里面说过了,这里的弹出指的就是删除,并返回。)
d1 = {'name':'suhaozhi','age':22}
print d1.pop('name')
suhaozhi
print d1
{'age': 22}
3.11 popitem 随机弹出,随机弹出字典的键值对,以元组的方式返回,删除的顺序是随机的!
d1 = {'name':'suhaozhi','age':22}
print d1.popitem()
('age', 22)
print d1
{'name': 'suhaozhi'}
3.12 setdefault 和get方法很像,用来获取指定key对应的值,当key不存在时,默认返回None,也可以手动指定返回值,基本上功能和get一样,不演示了。
3.13 update 使用一个字典更新另外一个字典,旧字典的内容会更新到新字典中,如果有相同的key,对应的值会被覆盖!!
d1 = {'name':'suhaozhi','age':22}
d2 = {'k1':'v1','k2':'v2','age':130}
d1.update(d2)
print d1
d2字典中的键值对,被更新到了d1字典中,相同的key被覆盖了。
3.14 values 获取字典中所有的值 ,以列表的方式返回。
d1 = {'name':'suhaozhi','age':22}
print d1.values()
3.15 itervalues 获取字典中所有的值,返回的是迭代器。
六.python集合(set)。
set集合中,每一个元素都是可hash的,在这个集合中是唯一的,不能重复,而且每个元素之间是无序的。
如何可以体现出set集合中每个元素的唯一性。
首先定义一个列表
[1,1,2,2,3,3,4,4,5,5,6,6]
将这个列表转换为set集合。
print set([1,1,2,2,3,3,4,4,5,5,6,6])
set([1, 2, 3, 4, 5, 6])
转换成集合之后,重复的元素被去掉了。
1.python集合中常用的方法。
1.1 add 在集合中添加一个元素。
s1 = set()
s1.add("suhaozhi")
print s1
set(['suhaozhi'])
1.2 update 将一个序列进行拆分,然后分别传入到集合中。
s1 = {"suhaozhi"}
s1.update([1,2,3,4,5])
print s1
set([1, 2, 3, 4, 5, 'suhaozhi'])
1.3 remove 移除一个元素。
s1 = {'suhaozhi',1,2,3,4,5,6}
s1.remove('suhaozhi')
print s1
set([1, 2, 3, 4, 5, 6])
集合中的suhaozhi被移除了。
1.4 issubset 用来测试,本集合中的每个元素是否都在另外一个集合中,也可以理解为另外一个集合是否包含本集合的所有元素。(以本集合为基准)
s1 = {'suhaozhi',1,2,3,4,5,6}
s2 = {6,5,4,3,2,1,'suhaozhi',222}
print s1.issubset(s2)
True
s2 中之要包含s1中所有的元素,返回结果就为真。
这个方法还可以使用两个符号代替,个人认为符号更容易记住。
s1.issubset(s2)可以写成这样 s1 <= s2
这两种语法的作用一模一样。
1.5 issuperset 和issubset方法类似,只不过方向上是相反的,另外一个集合中的每个元素是否包含在本集合中,也可以理解为本集合是否包含另外一个集合的所有元素。(以另外一个元素为基准)
s1 = {'suhaozhi',1,2,3,4,5,6}
s2 = {6,5,4,3,2,1,'suhaozhi',222}
print s1.issuperset(s2)
False
s1.issuperset(s2) 可以写成这样 s1 >= s2
这两种语法的作用也是一模一样的。
1.6 union 返回一个新的集合,这个集合中包含了两个集合中所有的元素,就是将两个元素融合。
s1 = {1,2,3}
s2 = {2,3,4}
print s1.union(s2)
set([1, 2, 3, 4])
union方法还可以使用|竖线代替。
s1 | s2 和 s1.union(s2) 功能是一样的。
1.7 intersection交集,取两个集合共同存在的元素。
s1 = {1,2,3}
s2 = {2,3,4}
print s1.intersection(s2)
set([2, 3])
s1.intersection(s2) 可以写成s1 & s2
1.8 difference差集,以本集合为中心,返回本集合有,但另一个集合没有的元素。
s1 = {1,2,3}
s2 = {2,3,4}
print s1.difference(s2)
set([1])
s1.difference(s2) 可以写成 s1-s2
1.9 symmetric_difference 返回一个新的集合,这个集合中,包含本集合和另一个集合不重复的元素。
s1 = {1,2,3}
s2 = {2,3,4}
print s1.symmetric_difference(s2)
s1.symmetric_difference(s2) 可以写成s1 ^ s2
1.10 copy 集合的浅复制,和字典的用法一样,在这就不做演示了。
1.11discard 如果存在就删除,如果当前集合中存在某个元素,发现存在就移除。
s2 = {2,3,4}
s2.discard(4)
print s2
set([2, 3])
1.12 pop 弹出集合中的一个元素,如果集合中没有元素可以弹出了,则抛出一个异常。
这个和列表的pop很类似,在这就不做演示了。
1.13 clear 真正意义上清空集合中的所有元素。
1.14 剩余的一些方法的补充。
intersection_update ,difference_update,symmetric_difference_update这些方法和intersection ,difference,symmetric_difference,基本上都是一样的,只不过带有update字样的方法会对原有集合进行操作,不带update的会生成一个新的集合。
本文转自苏浩智 51CTO博客,原文链接:http://blog.51cto.com/suhaozhi/1905917,如需转载请自行联系原作者