python基础--python的数据类型

当语句以冒号 : 结尾时,缩进的语句视为代码块。
缩进有利有弊。好处是强迫你写出格式化的代码,但没有规定缩进是几个空格还是Tab。按照约定俗成的管理,应该始终坚持使用 4个空格 的缩进。
Python程序是 大小写敏感 的,如果写错了大小写,程序会报错。

数据类型

计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值。但是,计算机能处理的远不止数值,还可以处理文本、图形、音频、视频、网页等各种各样的数据,不同的数据,需要定义不同的数据类型。在Python中,能够直接处理的数据类型有以下几种:
数据类型
  数字(整形,长整形,浮点型,复数)
  字符串
  列表
  元组
  字典
  集合

整数

Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如: 1 100 -8080 0 ,等等。
计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用 0x 前缀和0-9,a-f表示,例如: 0xff00 0xa5b4c3d2 ,等等。

浮点数

浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.23x10 9 和12.3x10 8 是完全相等的。浮点数可以用数学写法,如 1.23 3.14 -9.01 ,等等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.23x10 9 就是 1.23e9 ,或者 12.3e8 ,0.000012可以写成 1.2e-5 ,等等。
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。

字符串

字符串是以单引号 ' 或双引号 " 括起来的任意文本,比如 'abc' "xyz" 等等。请注意, '' "" 本身只是一种表示方式,不是字符串的一部分,因此,字符串 'abc' 只有 a b c 这3个字符。如果 ' 本身也是一个字符,那就可以用 "" 括起来,比如 "I'm OK" 包含的字符是 I ' m ,空格, O K 这6个字符。
如果字符串内部既包含 ' 又包含 " 怎么办?可以用转义字符 \ 来标识,比如:
'I\'m \"OK\"!'
表示的字符串内容是:
I'm "OK"!
转义字符 \ 可以转义很多字符,比如 \n 表示换行, \t 表示制表符,字符 \ 本身也要转义,所以 \\ 表示的字符就是 \ ,可以在Python的交互式命令行用 print() 打印字符串看看:
print ( 'I\'m ok.' )
效果如图所示:

 

print('I\'m learning\nPython.')

print('\\\n\\')

 

print('\\\n\\')

 

如果字符串里面有很多字符都需要转义,就需要加很多 \ ,为了简化,Python还允许用 r'' 表示 '' 内部的字符串默认不转义
print( '\\\t\\' )

 

 

print(r'\\\t\\')

如果字符串内部有很多换行,用\n写在一行里不好阅读,为了简化,Python允许用'''...'''的格式表示多行内容

 

注意在输入多行内容时,提示符由 >>> 变为 ... ,提示你可以接着上一行输入,注意 ... 是提示符,不是代码的一部分
当输入完结束符 ``` 和括号 ) 后,执行该语句并打印结果。
如果写成程序并存为 .py 文件,就是:
print('''line1
line2
line3''')

 

 

 

布尔值

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

 

布尔值可以用 and or not 运算。
and 运算是与运算,只有所有都为 True and 运算结果才是 True

 

 

 

 

or运算是或运算,只要其中有一个为Trueor运算结果就是True

not运算是非运算,它是一个单目运算符,把True变成FalseFalse变成True

not运算是非运算,它是一个单目运算符,把True变成FalseFalse变成True

 

 

布尔值经常用在条件判断中

空值

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

变量

变量的概念基本上和初中代数的方程变量是一致的,只是在计算机程序中,变量不仅可以是数字,还可以是任意数据类型。
变量在程序中就是用一个变量名表示了,变量名必须是大小写英文、数字和 _ 的组合,且不能用数字开头,比如:
a = 1
变量 a 是一个整数。
t_007 = 'T007'
变量 t_007 是一个字符串。
Answer = True
变量 Answer 是一个布尔值 True
在Python中,等号 = 是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,例如:
a = 123 # a是整数
print(a)
a = 'ABC' # a变为字符串
print(a)
加单引号双引号的都是字符串

 

 

 

变量在内存中的存储形式:
 
在python中, 每一个变量在内存中创建,我们可以通过变量来查看内存中的值

 

 

 

在python中通过指针改变变量的值
x = 1        说明x指向了内存中存储为1的地址,地址是1767137504
y = 2        说明y指向了内存 中存储为2的地址,地址是 1767137536
也就是说在执行x = 4,y = 5之后,x,y分别指向了不同的地址

 

 

 

当执行 x = y之后
x指向了y所指向的内存了,它们都指向同一块内存, 跟c里面的指针一样

linux 下

 

(好像linux(64bit ubuntu)和windows(64bit windows10)占用的内存大小不一样)
在python中,一开始初始化存储在内存的东西是不可以改变的,我们所能改变的只是它的指向。
示意图为

 

可以看出x和1的地址是一个地址,y的地址和2是一个地址。
所以
执行 x  = 1 ,解释器创建了整数 和变量 x ,并把 x 指向 1所在的内存地址
执行x  = y ,解释器创建了变量 y ,并把 y 指向 x 指向a的内存地址
如果将x重新赋值abc x='abc',那么 解释器创建了字符串'abc',并把 x 的指向改为 'abc'所在的内存地址 ,但 y 并没有更改

 

对变量赋值 x = y 是把变量 x 指向真正的对象,该对象是变量 y 所指向的。对变量 y 的赋值 不影响 变量 x 的指向。他们是独立的根据不同的操作指向不同的地址。
Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量关联起来。

常量

所谓常量就是不能变的变量,比如常用的数学常数π就是一个常量。在Python中,通常用全部大写的变量名表示常量:
PI = 3.14159265359
但事实上 PI 仍然是一个变量,Python根本没有任何机制保证 PI 不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法.
最后解释一下整数的除法为什么也是精确的。在Python中,有两种除法,一种除法是 /
>>> 10 / 3 3.3333333333333335
/ 除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数:
>>> 9 / 3 3.0
还有一种除法是 // ,称为地板除,两个整数的除法仍然是整数:
>>> 10 // 3 3
整数的地板除 // 永远是整数,即使除不尽。要做精确的除法,使用 / 就可以。
因为 // 除法只取结果的整数部分,所以Python还提供一个余数运算,可以得到两个整数相除的余数:
>>> 10 % 3 1
无论整数做 // 除法还是取余数,结果永远是整数,所以,整数运算结果永远是精确的。
注意:Python的整数没有大小限制,而某些语言的整数根据其存储长度是有大小限制的,例如Java对32位整数的范围限制在 -2147483648 - 2147483647
Python的浮点数也没有大小限制,但是超出一定范围就直接表示为 inf (无限大)。
 

list

Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。
例如:

 

M就是一个list
len() 函数可以获得list元素的个数:
len(M)

 

用索引来访问list中每一个位置的元素,记得索引是从 0 开始的:
M[0]
M[1]

 

 

当索引超出了范围时,Python会报一个IndexError错误,所以,要确保索引不要越界,记得最后一个元素的索引是len(M) - 1

 

 

如果要取最后一个元素,除了计算索引位置外,还可以用 -1 做索引,直接获取最后一个元素:
M[-1]

 

 

 

获取倒数第2个、倒数第3个:
M[-2]
M[-3]

 

list是一个可变的有序表,可以往list中追加元素到末尾:
M.append( 'd' )

 

 

 

也可以把元素插入到指定的位置,比如索引号为 1 的位置:
M.insert( 1 , 'e' )

如果该位置有数据,那么将当前数据插入该位置其他数据往后移动

 

 

 

要删除指定位置的元素,用 pop(i) 方法,其中 i 是索引位置:
例如:
M.pop(1)

 

要把某个元素替换成别的元素,可以直接赋值给对应的索引位置:
M[1]='B'

 

要把某个元素替换成别的元素,可以直接赋值给对应的索引位置:
M[1]='B'

 

list里面的元素的数据类型也可以不同,比如:
L = [ 'A' , 123 , True ]

 

list元素也可以是另一个list,比如:
s = [ 'python' , 'java' , [ 'asp' , 'php','go' ], 'C++','C' ]

 

还可以拆开写
m= [ 'asp' , 'php','go' ]
s= [ 'python' , 'java' , m , 'C++','C' ]

 

还可以拆开写
m= [ 'asp' , 'php','go' ]
s= [ 'python' , 'java' , m , 'C++','C' ]

 

获取java
s[1]

获取php

 

s 可以看成是一个二维数组
如果一个list中一个元素也没有,就是一个空的list,它的长度为0:

 

tuple

另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改
A=('a','b','c')

现在,A这个tuple不能变了,它也没有append(),insert()这样的方法。获取元素的方法和list是一样的,使用A[0]A[-1],但不能赋值成另外的元素。

当A为一个tuple时,使用append方法追加数据会报错

 

不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
当定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来,比如:

 

 
定义一个只有1个元素的tuple,如果这么定义:

 

定义的不是tuple,是 1 这个数!这是因为括号 () 既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是 1
所以,只有1个元素的tuple定义时必须加一个逗号 , ,来消除歧义:

 

 

tuple不可变但是如果存储的数据有列表list是可变的

其实tuple不变变化的只能是 list里面的内容

 

tuple中指向的数据一直是不可变的,指向的list地址也不变,list中的内容可以变化,list也是一个地址,地址中的内容可以变化
表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向 'a' ,就不能改成指向 'b' ,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!所有 tuple的不变应该是tuple每一个元素本身不能变。
如果tuple存一个变量,只要赋给tuple那么变量改变了tuple中的元素也不变

 

dict

Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
dict根据键值对来获取数据,存储的也是键值对
存储:d = { 'xiaoming' : 95 , 'xiaohong' : 90 , 'xiaowang' : 85 }
获取:d['xiaoming']

 

为什么dict查找速度这么快?因为dict的实现原理和查字典是一样的。假设字典包含了1万个汉字,我们要查某一个字,一个办法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法就是在list中查找元素的方法,list越大,查找越慢。
第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字。无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢。
dict就是第二种实现方式,给定一个名字,比如 'Michael' ,dict在内部就可以直接计算出 Michael 对应的存放成绩的“页码”,也就是 95 这个数字存放的内存地址,直接取出来,所以速度非常快。 这种key-value存储方式,在放进去的时候,必须根据key算出value的存放位置,这样,取的时候才能根据key直接拿到value。
字典是无序的,比如加一个数据,再取出。

由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:

 

相当于重新赋值
如果键不存在会报错


 

要避免key不存在的错误,有两种办法:

 

一是通过 in 判断key是否存在:

 

二是通过dict提供的 get() 方法,如果key不存在,可以返回 None ,或者自己指定的value:
存在

 

 

不存在

返回 None 的时候Python的交互环境不显示结果。
使用自定义返回值

 

 

 

删除一个key
pop(key) 方法,对应的value也会从dict中删除:

 

 

删除不存在的值会报错

 

dict内部存放的顺序和key放入的顺序是没有关系的。
和list比较,dict有以下几个特点:
  1. 查找和插入的速度极快,不会随着key的增加而变慢;
  2. 需要占用大量的内存,内存浪费多。
而list相反:
  1. 查找和插入的时间随着元素的增加而增加;
  2. 占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。
dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是 不可变对象
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:

 

 

 

#dict键值对互换

mydict={"a":1,"b":2,"c":3}

mydict_new={}

for key,val in mydict.items():

    mydict_new[val]=key

 

print(mydict_new)

 

 

mydict={"a":'A',"b":'B',"c":'C'}

mydict_new=dict([val,key] for key,val in mydict.items())

mydict={"a":'A',"b":'B',"c":'C'}
mydict_new= dict ( zip (mydict.values() , mydict.keys()))
print (mydict_new)

set

set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
要创建一个set,需要提供一个list作为输入集合:

 

传入的参数 [1, 2, 3] 是一个list,而显示的 {1, 2, 3} 只是告诉你这个set内部有1,2,3这3个元素,显示的顺序也不表示set是有序的。。
重复元素在set中自动被过滤:

通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果:

通过remove(key)方法可以删除元素:

 

set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
交集

 

 

并集

 

set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。
把list放入set,会报错。

 

切片
取一个list或tuple的部分元素是非常常见的操作。
定义一个list
L=[1,2,3,4,5,'a','b','c','d']
取前三个
可以使用
第一个办法
L=[1,2,3,4,5,'a','b','c','d']
print(L[0])
print(L[1])
print(L[2])
第二个办法
也可以使用循环
L=[1,2,3,4,5,'a','b','c','d']
m=[]
n=6
for i in range(n):
    m.append(L[i])
print(m)
第三个办法
使用第一种办法效率太差,第二种循环比较繁琐
python提供了切片操作可以大大简化这种繁琐的操作
L=[1,2,3,4,5,'a','b','c','d']    
d=L[0:6]
print(d)
L[0:6] 表示,从索引 0 开始取,直到索引 6 为止,但不包括索引 6 。即索引 1, 2, 3, 4, 5, 'a' 正好是6个元素(a的索引为5即6-1,第一个参数是从哪个索引开始,第二个是到N-1的索引结束或者理解为取第二个参数减去第一个参数的个数)切片可以大大简化繁琐的操作。
切片可以从前面取数据也可以从后面取数据

 

 

 

迭代(iteration)
 
迭代:iteration
可迭代的:Iterable
迭代器:iterator
迭代相比较迭代器更加抽象,这就好比,遍历一个字典dict,用到for...in...的操作,称之为在 迭代,而这种能遍历的行为或者能迭代的行为称之为可迭代的,而迭代器是具体到迭代行为的操作者或者说是实行者,在Python中有个函数专门返回的就是迭代器对象,而这个对象可以通过next的属性对dict同样进行遍历,我们又称这种现象为迭代器
在python中一个list或tuple,要想访问其中的某个元素,可以通过下标来访问,如果想要访问所有的元素,那可以用for循环来遍历这个list或者tuple,而这种遍历就叫做迭代。
在Python中,迭代通过for..in..来完成。
python的for循环不仅可以用在  list和tuple上,还可以作用在其他可迭代的对象上
例如:
d = { 'name' : 'Jack' , 'age' : 18 , 'job' : 'Coder' }
print (d) # 首先输出dict
print ( "迭代key" )
for s in d:
print (s)
 
print ( "迭代value" )
for value in d.values():
print (value)
print ( '迭代key和value' )
for k , v in d.items():
print ( 'key:%s,value:%s' % (k , v))

 

 

输出结果

 

字符串也可以进行迭代,迭代出每个字符:
for i in 'Hello World' :
    print (i , end = "" )

 

 

输出结果

 

 
可迭代的( Iterable
如果一个list、tuple或者一个字符串可以遍历,也就是有迭代的行为,称为是可以迭代的

结果

 

int型的数字不可迭代
字符串,list,tuple,dict,set等可以迭代
 
Python内置的enumerate函数可以把一个list变成 索引-元素对,这样就可以在for循环中同时迭代索引(下标)和元素(key)本身

输出结果:

 

print ( "list变成 索引-元素对" )
for index , value in enumerate ([ 'first' , 'second' , 'third' ]):
print (index , ":" , value)
print ( "dict变成 索引-元素对" )
for index , key in enumerate ({ 'first' : 1 , 'second' : 2 , 'third' : 3 }):
print (index , ":" , key)
 
迭代的对象实际上是一个list,这个list的每一个元素又是一个tuple,且每个tuple对象有N个元素,这样的话,就不能单单通过 for x in list:的方式来取了,应该可以这样写,for N1,N2,N3...in list:(要保证tuple的个数相等)

结果

如果不相等会报错

结果

 

迭代器(Iterator)
可以被 next() 函数调用并不断返回下一个值的对象称为迭代器: Iterator
可以直接作用于 for 循环的数据类型有以下几种:
一类是集合数据类型,如 list tuple dict set str 等;
一类是 generator ,包括生成器和带 yield 的generator function。
这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable
 
生成器都是 Iterator 对象,但 list dict str 虽然是 Iterable ,却不是 Iterator
 
可以使用 isinstance() 判断一个对象是否是 Iterator 对象
from   collections   import   Iterator
isinstance ((x   for   x   in   range ( 10 )), Iterator)
isinstance ([], Iterator)
isinstance ({}, Iterator)
isinstance ( 'abc' , Iterator)

 

 

 

list dict str Iterable 变成 Iterator 可以使用 iter() 函数
定义一个list,并通过iter获得list的迭代器对象
L = [ 'python2' , 'iter' , 26 , 'Python3' ]
it = iter (L) #获得list的迭代器对象
print (it)
while True :
x = next (it)
print (x)

 

 

输出结果报错

 

这是因为next()不知道什么时候停止
将代码修改下:
 
 
L = [ 'python2' , 'iter' , 26 , 'Python3' ]
it = iter (L) #获得list的迭代器对象
 
while True :
try : #try捕获异常
x= next (it)
print (x)
except StopIteration : #当捕获到迭代行为终止的时候,也就是无元素可以next的时候,终止循环
break


 

 

 

输出结果正常

 

为什么 list dict str 等数据类型不是 Iterator
因为Python的 Iterator 对象表示的是一个数据流,Iterator对象可以被 next() 函数调用并不断返回下一个数据,直到没有数据时抛出 StopIteration 错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过 next() 函数实现按需计算下一个数据,所以 Iterator 的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator 甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
 
小结
凡是可作用于 for 循环的对象都是 Iterable 类型;
凡是可作用于 next() 函数的对象都是 Iterator 类型,它们表示一个惰性计算的序列;
集合数据类型如 list dict str 等是 Iterable 但不是 Iterator ,不过可以通过 iter() 函数获得一个 Iterator 对象。
Python的 for 循环本质上就是通过不断调用 next() 函数实现的,例如:
for   x   in   [ 1 ,   2 ,   3 ,   4 ,   5 ]:
    print(x)
等价于
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5 ])
# 循环: while True:
try :
# 获得下一个值:
x = next(it)
except StopIteration:
# 遇到StopIteration就退出循环
break

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值