1可变对象和不可变对象

         python中,主要的数据类型为字符串,数字,列表,元祖和字典,其中字符串,数字和元祖为不可变类型,而列表和字典属于可变类型。

         在强调可变类型和不可变类型的时候,只要是在复制的时候,是浅拷贝还是深拷贝,一个数据的修改会不会造成另外的一个引用也发生变化,如下所示:

>>> alist = [1,2] 可变对象list

>>> blist = alist alistblist指向同一个对象,也就是引用了同一块内存地址,内存地址中放着列表

>>> blist[1]="changed" 修改其中的值

>>> alist

[1, 'changed']

>>> blist 由于引用的是同一个对象,从而两者都会发生变化

[1, 'changed']

>>> alist is blist is表示两者是否同一个对象,也就是引用的内存地址是否相同

True

>>> atuple = (1,2,[1,2]) (不可变对象tuple)

>>> btuple = atuple 两者引用同一个对象

>>> id(atuple) 指向的内存地址相同

139987083454816

>>> id(btuple)

139987083454816

>>> atuple[2][1]="changed" 元祖的值不可变,但是如果包含了可变对象,还是可以变化的

>>> atuple,btuple两者都发生了变化

((1, 2, [1, 'changed']), (1, 2, [1, 'changed']))

>>> id(atuple),id(btuple)引用的内存地址未发生变化

(139987083454816, 139987083454816)

         从而在进行复制的时候,需要小心,有的时候在进行赋值的时候,可能在其他的地方发生了修改,在直接赋值的时候,基本上是浅拷贝,如果要想重新创建一个对象,从而可以使用深拷贝,如下所示:

>>> import copy导入模块copy,主要用来做深拷贝

>>> alist = [1,2,3]

>>> blist = copy.deepcopy(alist) 深拷贝的引用赋值给blist

>>> id(alist),id(blist) 两者指向的对象不同

(139987097637376, 139987097642696)

>>> alist[1] = "changed"

>>> alist,blist 一个修改不会影响另外的一个对象

([1, 'changed', 3], [1, 2, 3])

 

2字符串和数值类型

         字符串类型和数值类型都是不可变对象,但是字符串是一个容器对象,从而可以进行切片,可以看做是一个序列,可以使用下标来进行引用,如下所示:

>>> a = "hello world"

>>> b = a 两者引用同一个对象

>>> id(a),id(b)

(139987083474768, 139987083474768)

>>> a = "changed" 修改的时候,不会同时发生修改,会创建一个新的对象,从而体现了字符串的不可变对象

>>> a,b,id(a),id(b) id表示内存地址,也就是变量指向的地址

('changed', 'hello world', 139987083475632, 139987083474768)

>>> a[1:2] 字符串属于容器类型,从而可以做切片操作,表示取第一个元素

'h'

>>> a[1:3:1] 扩展的切片操作,可以指定开始位置,结束位置和步长

'ha'

>>> a[::-1] 将字符串进行倒序输出,-1表示最后一个元素

'degnahc'

>>> a[-1:-3:-1] 从左到右是0lena),从右到左是-1-lena

'de

>>> a.startswith('hello') 字符串方法,判断以什么开头

False

>>> " " .join(a) 连接容器类的元素

'c h a n g e d'

>>> a = 1.0 数值类型

>>> b = 1.0

>>> id(a),id(b) 不可变对象两者引用的内存地址不同

(38405792, 38405768)

>>> a = 1

>>> b = 1

>>> id(a),id(b) python在内部会高效缓存简单数字0-100,从而两者的内存地址一致

(38334808, 38334808)

 

3列表和元祖

         列表属于可变对象,元祖属于不可变对象,列表中的值能直接进行修改,而元祖的值是不能修改的,但是如果元祖中包含了可变对象,那么依旧是可以修改的,两者都是序列类型,从而可以通过下标进行引用,在列表包含的方法比较多,而元祖由于不能发生改变,从而没有啥方法,基本的操作如下所示:

>>> alist = [1,2,3,"xyz"] 创建list

>>> alist[1]使用下标取值

2

>>> alist[2:]list属于序列,从而支持切片操作

[3, 'xyz']

>>> alist.append("add item")list后面添加新元素

>>> alist.count("add item")统计list中元素的个数

1

>>> alist.index(1)取出第一次出现值1的索引

0

>>> alist.insert(1,"add position1")在某个位置插入新的元素

>>> alist.sort()list是有序的,从而可以对list进行排序

>>> alist

[1, 2, 3, 'add item', 'add position 1', 'xyz']

>>> alist.remove("xyz")移除元素

>>> alist

[1, 2, 3, 'add item', 'add position 1']

>>> alist.pop()随机pop一个元素,返回值

'add position 1'

>>> alist.pop(1)指定位置pop元素,返回值

2

>>> alist

[1, 3, 'add item']

>>> alist.reverse()list进行反转操作

>>> alist

['add item', 3, 1]

>>> blist = [1,2,3]

>>> alist.extend(blist)扩展列表,将另外一个列表加入到现在的列表中

>>> alist

['add item', 3, 1, 1, 2, 3]

>>> len(alist)列表的长度

6

>>> atuple = (1)

>>> type(atuple)

<type 'int'>

>>> atuple = (1,) 在只有一个元素的时候创建tuple,必须使用逗号

>>> type(atuple)

<type 'tuple'>

>>> atuple[1] 超出索引范围会报错)

Traceback (most recent call last):

  File"<stdin>", line 1, in <module>

IndexError: tuple index out of range

>>> atuple[0]根据索引取值

1

>>> atuple.count(1)统计元素的个数

1

>>> atuple.index(1)找出元素的索引

0

4字典

         字典是可变对象,并且是属于序列对象,以键值对的形式存在,在访问的时候,不同于listtyple,必须通过映射的方式来进行访问,也就是必须通过键,然后才得到相应元素的值,如下所示:

>>> adict = {}创建空字典

>>> adict ={"key":"value","age":22} 创建字典有很多方式,这是其中之一

>>> adict['key']字典必须通过键来进行引用字典的值

'value'

>>> adict.items()查看键值对的元祖的列表

[('age', 22), ('key', 'value')]

>>> adict.keys()查看字典的所有键,返回一个列表

['age', 'key']

>>> adict.values() 查看字典的值,返回一个列表

[22, 'value']

>>> adict.iterkeys()查看字典的键,返回的是一个迭代器

<dictionary-keyiterator object at0x7f5148613260>

>>> adict.itervalues()

<dictionary-valueiterator object at0x7f51486135d0>

>>> for i in adict.iterkeys():循环迭代取值

...  print i

...

age

key

>>> adict.viewkeys()

dict_keys(['age', 'key'])

>>> adict.viewvalues()

dict_values([22, 'value'])

>>> adict.viewitems()

dict_items([('age', 22), ('key', 'value')])

>>> for i in adict.viewkeys():

...  print i

...

age

name

key

>>> adict

{'age': 22, 'key': 'value'}

>>> bdict ={"name":"kel"}

>>> adict.update(bdict)将一个字典加入到另外一个字典之中

>>> adict

{'age': 22, 'name': 'kel', 'key': 'value'}

5几个有用的内置函数

         几个比较有用的函数如下所示:

>>> dir()(查看当前环境)

['__builtins__', '__doc__', '__name__','__package__', 'atexit']

>>> type(int)type用来查看对象的类型

<type 'type'>

>>> a = 1

>>> id(a)id用来查看对象的内存地址

33026392

>>> b = 1

>>> a is b is用来比较两个对象的引用是否相同,也就是内存地址是否相同

True

>>> dir(a) dir可以查看对象的函数和属性

['__abs__', '__add__', '__and__','__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__','__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__','__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__','__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__','__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__','__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__','__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__','__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__','__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__','__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length','conjugate', 'denominator', 'imag', 'numerator', 'real']

>>> help(a)