Python学习——基础数据类型

本节主要讲述python的数据类型,以及数据类型相关的内置函数。这是python最基础的部分,所以不能学的模糊不清。

1. 整数

Python可以处理任意大小的整数,包括负整数,在程序中的表示方法和数学上的写法一模一样例如:1,100,-8080,0
二进制数以0b或者0b开头
八进制数以0o或者0o开头
十六进制以0x或者0x开头
Python 3中的整数是无限大小的。 Python 2 有两个整数类型 - int和long。 Python 3中没有“长整数”
python整数比较:
在 Python 中一切都是对象,毫无例外整数也是对象,对象之间比较是否相等可以用==,也可以用is。
==和is操作的区别是:
is:比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对象,是否指向同一个内存地址。
==:比较的是两个对象的内容是否相等,默认会调用对象的eq()方法。

>>> a = 256
>>> b = 256
>>> a == b
True
>>>
>>> a = 257
>>> b = 257
>>> a == b
True
>>> a is b
False

解惑:
出于对性能的考虑,Python内部做了很多的优化工作,对于整数对象,Python把一些频繁使用的整数对象缓存起来,保存到一个叫small_ints的链表中,在Python的整个生命周期内,任何需要引用这些整数对象的地方,都不再重新创建新的对象,而是直接引用缓存中的对象。Python把这些可能频繁使用的整数对象规定在范围[-5, 256]之间的小对象放在small_ints中,但凡是需要用些小整数时,就从这里面取,不再去临时创建新的对象。因为257不再小整数范围内,因此尽管a和b的值是一样,但是他们在Python内部却是以两个独立的对象存在的,各自为政,互不干涉。

>>> c = 257
>>> def foo():
...  a = 257
...  b = 257
...  print a is b
...  print a is c
>>> foo()
True
False

解惑:
Python程序由代码块构成,代码块作为程序的一个最小基本单位来执行。一个模块文件、一个函数体、一个类、交互式命令中的单行代码都叫做一个代码块。在上面这段代码中,由两个代码块构成,c = 257作为一个代码块,函数foo作为另外一个代码块。Python内部为了将性能进一步的提高,凡是在一个代码块中创建的整数对象,如果存在一个值与其相同的对象于该代码块中了,那么就直接引用,否则创建一个新的对象出来。Python出于对性能的考虑,但凡是不可变对象,在同一个代码块中的对象,只有是值相同的对象,就不会重复创建,而是直接引用已经存在的对象。因此,不仅是整数对象,还有字符串对象也遵循同样的原则。所以 a is b就理所当然的返回True了,而c和a不在同一个代码块中,因此在Python内部创建了两个值都是257的对象。

2. 浮点数

浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.23x109和12.3x108是完全相等的。浮点数可以用数学写法,如1.23,3.14,-9.01,等等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.23x109就是1.23e9,或者12.3e8,0.000012可以写成1.2e-5,等等。
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差
1,浮点数的取值范围为正负10的308次方,精度为10的-16次方,
2,浮点数的运算存在不确定尾数,也就是说0.1+0.2 == 0,3会被判断为False,就是因为不确定尾数导致的,其根本原因还是二进制数和十进制数不存在严格的对等关系导致的,由于精度

>>> 0.1+0.2 == 0.3
False
>>> 0.1+0.2
0.30000000000000004

3,为了解决不确定尾数的问题,可以采用round(x,d)函数来进行四舍五入,x是目标数字,d是小数点后几位,表示精度。这个函数经常在10的-16次方左右十分有效,
4,浮点数的科学计数法,可以用(a)e(b)表示a乘以10的b次方,例如9e5

3. complex 复数

复数是以a + bj的形式,其中a和b是浮点,J(或j)表示-1的平方根(虚数)。数字的实部是a,虚部是b。假设z是一个复数,可以用z.imag获得复数的虚部,可以用z.real获得复数的实部

4. str 字符串

字符串是以单引号’或双引号”括起来的任意文本,比如’abc’,”xyz”等等。请注意,”或”“本身只是一种表示方式,不是字符串的一部分,因此,字符串’abc’只有a,b,c这3个字符。如果’本身也是一个字符,那就可以用”“括起来,比如”I’m OK”包含的字符是I,’,m,空格,O,K这6个字符。如果字符串内部既包含’又包含”怎么办?可以用转义字符\来标识
如果字符串里面有很多字符都需要转义,就需要加很多\,为了简化,Python还允许用r”表示”内部的字符串默认不转义,Python允许用”’…”’的格式表示多行内容
字符串操作符:
下表实例变量 a 值为字符串 “Hello”,b 变量值为 “Python”:

操作符 说明 示例
+ 字符串连接 a + b ‘HelloPython’
* 重复输出字符串 a * 2 ‘HelloHello’
[] 通过索引获取字符串中字符 a[1] ‘e’
[:] 截取字符串中的一部分 a[1:4] ‘ell’
in 成员运算符 - 如果字符串中包含给定的字符返回 True “H” in a True
not in 成员运算符 - 如果字符串中不包含给定的字符返回 “M” not in a True
r/R 所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符 printf(r’\n’) >>> print R’\n’ \n

布尔值和布尔代数的表示完全一致,一个布尔值只有True、False两种值,要么是True,要么是False,在Python中,可以直接用True、False表示布尔值(请注意大小写),也可以通过布尔运算计算出来

5. None 空值

空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值

6. list 列表

Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。用len()函数可以获得list元素的个数当索引超出了范围时,Python会报一个IndexError错误,所以要确保索引不要越界,记得最后一个元素的索引是len(classmates) - 1。如果要取最后一个元素,除了计算索引位置外,还可以用-1做索引,直接获取最后一个元素。list是一个可变的有序表,所以可以往list中追加元素到末尾

7. tuple 元组

另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改。它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样要定义一个空的tuple,可以写成()要定义一个只有1个元素的tuple,(1,),Python在显示只有1个元素的tuple时,也会加一个逗号,,以免你误解成数学计算意义上的括号
最后来看一个“可变的”tuple:

>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])

表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向’a’,就不能改成指向’b’,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!

8. dict 字典

Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉
如果key不存在,dict就会报错要避免key不存在的错误,有两种办法,一是通过in判断key是否存在;二是通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value,## 标题 ##
注意:返回None的时候Python的交互环境不显示结果
要删除一个key,用pop(key)方法,对应的value也会从dict中删除
请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。
和list比较,dict有以下几个特点:
查找和插入的速度极快,不会随着key的增加而变慢;
需要占用大量的内存,内存浪费多。
而list相反:
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。
dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key

9. set 集合

set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。要创建一个set,需要提供一个list作为输入集合通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果通过remove(key)方法可以删除元素set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的

10.列表及元组切片操作

取一个list或tuple的部分元素是非常常见的操作。比如,一个list如下:
L = [‘Michael’, ‘Sarah’, ‘Tracy’, ‘Bob’, ‘Jack’]
取前3个元素,应该怎么做?
笨办法:
[L[0], L[1], L[2]]
[‘Michael’, ‘Sarah’, ‘Tracy’]
之所以是笨办法是因为扩展一下,取前N个元素就没辙了。
取前N个元素,也就是索引为0-(N-1)的元素,可以用循环:

>>> r = []
>>> n = 3
>>> for i in range(n):
...     r.append(L[i])
... 
>>> r
['Michael', 'Sarah', 'Tracy']

对这种经常取指定索引范围的操作,用循环十分繁琐,因此,Python提供了切片(Slice)操作符,能大大简化这种操作。
对应上面的问题,取前3个元素,用一行代码就可以完成切片:

>>> L[0:3]
['Michael', 'Sarah', 'Tracy']

L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。
如果第一个索引是0,还可以省略:

>>> L[:3]
['Michael', 'Sarah', 'Tracy']

也可以从索引1开始,取出2个元素出来:

>>> L[1:3]
['Sarah', 'Tracy']

类似的,既然Python支持L[-1]取倒数第一个元素,那么它同样支持倒数切片,试试:

>>> L[-2:]
['Bob', 'Jack']
>>> L[-2:-1]
['Bob']

记住倒数第一个元素的索引是-1。
切片操作十分有用。我们先创建一个0-99的数列:

>>> L = list(range(100))
>>> L
[0, 1, 2, 3, ..., 99]

可以通过切片轻松取出某一段数列。比如前10个数:

>>> L[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

后10个数:

>>> L[-10:]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

前11-20个数:

>>> L[10:20]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

前10个数,每两个取一个:

>>> L[:10:2]
[0, 2, 4, 6, 8]

所有数,每5个取一个:

>>> L[::5]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]

甚至什么都不写,只写[:]就可以原样复制一个list:

>>> L[:]
[0, 1, 2, 3, ..., 99]

tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:

>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)

字符串’xxx’也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:

>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[::2]
'ACEG'

在很多编程语言中,针对字符串提供了很多各种截取函数(例如,substring),其实目的就是对字符串切片。Python没有针对字符串的截取函数,只需要切片一个操作就可以完成,非常简单。
练习:利用切片操作,实现一个trim()函数,去除字符串首尾的空格

def trim(s):
    '''首先判断该字符串是否为空,如果为空,就返回该字符串,
    如果不为空的话,就判断字符串首尾字符是否为空,
    如果为空,就使用递归再次调用该函数trim(),否则就返回该函数'''
    if len(s) == 0:
        return s
    elif s[0] == ' ':
        return (trim(s[1:]))
    elif s[-1] == ' ':
        return (trim(s[:-1]))
    return s

猜你喜欢

转载自blog.csdn.net/zhaoyun_zzz/article/details/80779487