2.python基础之—列表,元组,字典,集合,字符串的使用方法

  1. 云栖社区>
  2. 博客>
  3. 正文

2.python基础之—列表,元组,字典,集合,字符串的使用方法

技术小胖子 2017-11-14 15:35:00 浏览1119
展开阅读全文

一.关于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,如需转载请自行联系原作者






网友评论

登录后评论
0/500
评论
技术小胖子
+ 关注