# 07-Python数据类型 **Python有五个常用数据类型** - ​ Numbers 数字 - ​ String 字符串 - ​ List 列表 - ​ Tuple 元组 - ​ Dictionary 字典 - ​ Set 集合 用来去重 **其他分类方式** 序列类型: 字符串、列表、元组、Unicode字符串,buffer对象,range对象 泛映射类型: 字典 集合: set() ## 一、数字 用于存储数值,是不变的数据类型,也就是说改变数字数据类型会分配一个新的对象。 当你指定一个值时,Number对象就会被创建 ```python var1 = 1 var1,var2=1,10 ``` **使用del删除一些对象的引用** ```python del var1[,var2[,var3[....,varN]]]] ``` 例 ```python del var del var_a, var_b ``` **Python常用数字类型** - ​ int 有符号整型 - ​ float 浮点型 除了 [`int`](https://docs.python.org/zh-cn/3.12/library/functions.html#int) 和 [`float`](https://docs.python.org/zh-cn/3.12/library/functions.html#float),Python 还支持其他数字类型,例如 [`Decimal`](https://docs.python.org/zh-cn/3.12/library/decimal.html#decimal.Decimal) 或 [`Fraction`](https://docs.python.org/zh-cn/3.12/library/fractions.html#fractions.Fraction)。Python 还内置支持 [复数](https://docs.python.org/zh-cn/3.12/library/stdtypes.html#typesnumeric),后缀 `j` 或 `J` 用于表示虚数(例如 `3+5j` )。 **数值类型实例** | int | float | complex | | ------ | ---------- | ---------- | | 10 | 0.0 | 3.14j | | 100 | 15.20 | 45.j | | -786 | -21.9 | 9.322e-36j | | 080 | 32.3+e18 | .876j | | -0490 | -90. | -.6545+0J | | -0x260 | -32.54e100 | 3e+26J | | 0x69 | 70.2-E12 | 4.53e-7j | 注:复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示,复数的实部a和虚部b都是浮点型 浮点型float ```python >>> f=12 >>> type(f) >>> f=12.0 >>> type(f) ``` 复数类型:应用于系统分析、信号分析、量子力学、相对论、应用数学、流体力学、碎形 ```python >>> j=3.12 >>> type(j) >>> j=3.12j //在原来数字基础上加j >>> type(j) ``` 严格来讲,bool类型就是bool类型 bool(布尔型)   真 或 假   1 或 0 True 或 False ```python >>> a=1==1 >>> a True >>> a=bool(1==1) >>> a True >>> a=bool(1=="1") >>> a False >>> type(a) ``` ## 二、字符串 表示文本 字符串是immutable的 **immutable -- 不可变对象** 具有固定值的对象。不可变对象包括 *数字、字符串和元组*。这样的对象不能被改变。如果必须存储一个不同的值,则必须创建新的对象。它们在需要常量哈希值的地方起着重要作用,例如作为字典中的键。 **创建字符串** 使用引号创建字符串 ```python var1 = 'Hello World!' var2 = "Python fklinux" var3 = '''Python fklinux''' ``` ### 字符串切片 **字符串取值顺序** 1、从左到右索引默认0开始的,最大范围是字符串长度少1 2、从右到左索引默认-1开始的,最大范围是字符串开头 用`'变量[头下标:尾下标:步长]'`,就可截取相应的字符串,其中下标是从0开始算起,可以是正数或负数,下标可以为空表示取到头或尾。 ```python s = 'ilovepython' s[1:5]的结果是love ``` 当使用以冒号分隔的字符串,返回一个新对象,结果包含以这对偏移标识的连续内容, 左边的开始包含下边界,取到的最大范围不包括上边界。 ```python #!/usr/bin/python3.8 str = 'Hello World!' print (str) print (str[:]) print (str[::]) # 以上3种都是输出完整字符串 print (str[::1]) # 最后面的数字是步长,步长为1 print (str[::2]) # 步长为2 print (str[0]) # 输出字符串中的第一个字符 print (str[-1]) # 输出倒数第1个字符 print (str[-2]) # 输出倒数第2个字符 print (str[-3:-1]) # 输出倒数第3和第2个字符 print (str[-1:-3]) # 这样会有问题,因为默认是从做往右取值,可以在最后指定负值的步长表示从右往左取值 print (str[-1:-3:-1]) print (str[2:5]) # 输出字符串中第三个至第五个之间的字符串 print (str[2:]) # 输出从第三个字符开始的字符串 print (str * 2) # 输出字符串两次 print (str + "TEST") # 输出连接的字符串 ``` **转义字符** 需要在字符中使用特殊字符时,用反斜杠`\`转义字符。 | 转义字符 | 描述 | | --------- | -------------------------------------------- | | \在行尾时 | 续行符 | | \\\ | 反斜杠符号 | | \a | 响铃 | | \b | 退格(Backspace) | | \n | 换行 | | \v | 纵向制表符 | | \t | 横向制表符 | | \r | 回车 | | \f | 换页 | | \oyy | 八进制数,yy代表的字符,例如:\o12代表换行 | | \xyy | 十六进制数,yy代表的字符,例如:\x0a代表换行 | | \other | 其它的字符以普通格式输出 | **原始字符串** ```python # 如果不想让转义字符生效,只想显示字符串原来的意思,用r定义原始字符串, r和R效果相同 print(r'\t\r') 实际输出为:"\t\r" ``` **字符串运算符** 下表实例变量a值为字符串"Hello",b变量值为"Python": - \+ 字符串连接 a + b 输出结果: HelloPython - \* 重复输出字符串 a*2 输出结果:HelloHello - 支持成员运算符 in 和 not int 相邻的两个或多个 *字符串字面值* (引号标注的字符)会自动合并: ```python >>> 'Py' 'thon' 'Python' ``` 拼接分隔开的长字符串时,这个功能特别实用: ```python >>> text = ('Put several strings within parentheses ' ... 'to have them joined together.') >>> text 'Put several strings within parentheses to have them joined together.' ``` 这项功能只能用于两个字面值,不能用于变量或表达式: ```python >>> prefix = 'Py' >>> prefix 'thon' # can't concatenate a variable and a string literal File "", line 1 prefix 'thon' ^^^^^^ SyntaxError: invalid syntax >>> ('un' * 3) 'ium' File "", line 1 ('un' * 3) 'ium' ^^^^^ SyntaxError: invalid syntax ``` 合并多个变量,或合并变量与字面值,要用 `+`: ```python >>> prefix + 'thon' 'Python' ``` \+可以用于字符串更新 你可以对已存在的字符串进行修改,并赋值给另一个变量 ```python #!/usr/bin/python3.8 var1 = 'Hello World!' print ("更新字符串 :- ", var1[:6] + 'wing!') 结果: 更新字符串 :- Hello wing! ``` ```python #!/usr/bin/python3.8 a = "Hello" b = "Python" print ("a + b 输出结果:", a + b) print ("a * 2 输出结果:", a * 2 ) print ("a[1] 输出结果:", a[1] ) print ( "a[1:4] 输出结果:", a[1:4] ) if( "H" in a) : print ("H 在变量 a 中" ) else : print("H 不在变量 a 中" ) if( "M" not in a) : print("M 不在变量 a 中" ) else : print("M 在变量 a 中") print(r'\n') print(R'\n') 结果: a + b 输出结果: HelloPython a * 2 输出结果: HelloHello a[1] 输出结果: e a[1:4] 输出结果: ell H 在变量 a 中 M 不在变量 a 中 \n \n ``` ### 格式化打印 python2格式化方法:使用% ```python #!/usr/bin/python print("My name is %s and ===========weight\t\n is %d kg!" % ('Zara', 21)) %s 字符串 %d 整数 %f 浮点数 结果: My name is Zara and weight is 21 kg! 注:Bash格式化打印语法 # printf "...%d %f %s" 5 6.3 "hello" ``` python3格式化方法:主打format ```python In [4]: print( '{0},{1}'.format('hello',2) ) hello,2 In [88]: print('{1}----{0}'.format('hello',2)) 2----hello In [5]: print('{},{},{}'.format('hello',2,3)) hello,2,3 In [6]: print ( '{name},{gender},{age}' . format (age = 32 ,gender = 'male' ,name = 'liying' )) liying,male,32 # 格式限定符 # 它有着丰富的的"格式限定符"(语法是{}中带:号),比如: # 填充与对齐,填充常跟对齐一起使用 # ^、<、>分别是居中、左对齐、右对齐,后面带宽度 # :号后面带填充的字符,只能是一个字符,不指定默认是用空格填充 # 8是字符串宽度 In [9]: print ( '{:>8}' . format ( 'liying' )) # 没有指定填充字符,默认用空格填充 liying In [9]: print ( '{1:>8}' . format ( 'liying' )) # 没有指定填充字符,默认用空格填充 liying # 1代表的是索引位置 In [10]: print ( '{:0>8}' . format ( 'liying' )) # 用0填充 00liying In [11]: print ( '{:a>8}' . format ( 'liying' )) # 用字符a填充 aaliying # 精度与类型f,精度常跟类型f一起使用 In [13]: print ( '{:.2f}' . format ( 31.31412 )) # 指定小数点位数为2位 31.31 In [101]: print('{:>10.3f}'.format(3.1415926)) # >10 指定宽度为10且右对齐 3.142 # 进制,b、d、o、x分别是二进制、十进制、八进制、十六进制 In [15]: print ( '{:b}' . format ( 15 )) 1111 In [16]: print ( '{:d}' . format ( 15 )) 15 In [17]: print ( '{:o}' . format ( 15 )) 17 In [18]: print ( '{:x}' . format ( 15 )) f # 用逗号做金额的千位分隔符 In [22]: print ( '{:,}' . format ( 123456789 )) 123,456,789 ``` python3.0 print函数新语法,可以让print附带参数 ```python >>> print("a",sep=':') a:b In [109]: print("abc","def",sep="|",end='') abc|def separater end ``` 三引号(triple quotes) 可以将复杂的字符串进行复制,允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。 ```python >>> hi ='''hi there''' >>> hi ='''hi\nthere''' ``` ### 字符串方法 | 方法 | 描述 | | ------------------------------------------------- | ------------------------------------------------------------ | | *string.find(str, beg=0, end=len(string)) | 检测 str 是否包含在 string 中,如果是 beg 和 end 指定范围,则检查是否包含在指定范围内,如果是则返回开始的索引值,否则返回-1 | | *string.index(str,beg=0,end=len(string)) | 跟find()方法一样,只不过如果str不在 string中会报一个异常. | | *string.isalnum() | 如果 string 至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False | | *string.isalpha() | 如果 string 至少有一个字符并且所有字符都是字母则返回 True, 否则返回 False | | *string.isdigit() | 如果 string 只包含数字则返回 True 否则返回 False. | | *string.islower() | 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False | | *string.isnumeric() | 如果 string 中只包含数字字符,则返回 True,否则返回 False | | *string.isspace() | 如果 string 中只包含空格,则返回 True,否则返回 False. | | *string.istitle() | 如果 string 是标题化的(见 title())则返回 True,否则返回 False | | *string.isupper() | 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False | | *string.join(seq) | 以 string 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串 | | *string.ljust(width) | 返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串 | | *string.lower() | 转换 string 中所有大写字符为小写. | | *string.lstrip() | 截掉 string 左边的空格 | | *string.maketrans(intab, outtab]) | maketrans() 方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。 | | *string.partition(str) | 有点像 find()和 split()的结合体,从 str 出现的第一个位置起,把字符串 string 分 成 一 个 3 元 素 的 元 组 (string_pre_str,str,string_post_str),如果 string 中不包含str 则 string_pre_str == string. | | *string.replace(str1,str2,num=string.count(str1)) | 把 string 中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次. | | *string.rfind(str, beg=0,end=len(string) ) | 类似于 find()函数,不过是从右边开始查找. | | *string.rindex( str, beg=0,end=len(string)) | 类似于 index(),不过是从右边开始. | | *string.rjust(width) | 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串 | | *string.rpartition(str) | 类似于 partition()函数,不过是从右边开始查找. | | *string.rstrip() | 删除 string 字符串末尾的空格. | | *string.split(str="", num=string.count(str)) | 以 str 为分隔符切片 string,如果 num有指定值,则仅分隔 num 个子字符串 | | *string.splitlines(num=string.count('\n')) | 按照行分隔,返回一个包含各行作为元素的列表,如果 num 指定则仅切片 num 个行. | | *string.startswith(obj, beg=0,end=len(string)) | 检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查. | | *string.strip([obj]) | 在 string 上执行 lstrip()和 rstrip() | | *string.swapcase() | 翻转 string 中的大小写 | | *string.title() | 返回"标题化"的 string,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle()) | | *string.translate(str, del="") | 根据 str 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 del 参数中 | | *string.upper() | 转换 string 中的小写字母为大写 | | *string.zfill(width) | 返回长度为 width 的字符串,原字符串 string 右对齐,前面填充0 | | string.isdecimal() | isdecimal()方法检查字符串是否只包含十进制字符。这种方法只存在于unicode对象。 | ```python # 把字符串的第一个字符大写 In [11]: a='hello world' In [14]: a.capitalize() Out[14]: 'Hello world' ``` ```python # 字符串的每个单词开头字符大写 In [7]: import string In [8]: string.capwords("hello world") Out[9]: 'Hello World' ``` ```python # 返回一个原字符串居中,并使用空格填充至长度为 width 的新字符串,这里的宽度为20 In [20]: a.center(20) Out[20]: ' hello world ' ``` ```python string.count(str, beg=0, end=len(string)) 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数 beg开始的位置 end结束的位置 ,不包括结束位置 In [21]: a.count('l') Out[21]: 3 In [22]: a.count('l',3) Out[22]: 2 In [23]: a.count('l',3,9) Out[23]: 1 In [24]: a.count('l',3,10) Out[24]: 2 ``` ```python string.endswith(obj, beg=0, end=len(string)) 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False. beg开始的位置 end结束的位置 In [25]: a.endswith('ld') Out[25]: True In [28]: a.endswith('o',2,5) Out[28]: True In [29]: a.endswith('o',2,4) Out[29]: False ``` ```python string.expandtabs(tabsize=8) 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8。 注意:这里的8最后转换后会是7个空格,如果指定成3会是2个空格 In [34]: a='hello\tworld' In [35]: print(a) hello world In [36]: a.expandtabs() Out[36]: 'hello world' ``` 使用方法举例: ```python In [9]: hero = "i'm wing" In [10]: hero.title() Out[10]: "I'M Wing" ``` 也可以直接使用模块实现各种字符串方法: ```python In [13]: import string In [14]: hero="i am wing" In [15]: string.capwords(hero) Out[15]: 'I Am Wing' ``` **大小写转化** ```python #vim upper_lower_string.py #!/usr/bin/python3.8 string = "Hello Wing" print(string.lower()) print(string.upper()) 结果如下 # python upper_lower_string.py hello wing HELLO WING ``` **去除空白** ```python #!/usr/bin/python3.8 string = "\nhello,this is a strip test\n" string_1 = "" a="-" for i in range(4): print (a*40) if i == 0: print ("'string'变量所存储字符串的原始打印格式为:") print (string) elif i == 1: print ("'string'使用字符串方法'lstrip'后去掉了字符串前面的空白,打印格式为:") print (string.lstrip()) elif i == 2: print ("'string'使用字符串方法'rstrip'后去掉了字符串后面的空白,打印格式为:") print (string.rstrip()) else: print ("'string'使用字符串方法'strip'后去掉了字符串前面和后面的空白,打印格式为:") print (string.strip()) else: print (a*40) print ('注:在lstrip()、rstrip()、strip()没有参数的情况下会删除空白,"tab、空格、换行、回车"都属于"空白"') for i in range(4): print (a*40) if i == 0: print ("'string_1'变量所存储字符串的原始打印格式为:") print (string_1) elif i == 1: print ('''"string_1"使用字符串方法lstrip("<")后去掉了字符串前面的"<",打印格式为:''') print (string_1.lstrip("<")) elif i == 2: print ( '''"string_1"使用字符串方法rstrip(">")后去掉了字符串后面的">",打印格式为:''') print (string_1.rstrip(">")) else: print ('''"string_1"使用字符串方法strip("<").strip(">")后去掉了字符串前面和后面的空白,打印格式为:''') print ( string_1.strip("<").strip(">")) else: print ( a*40) print ('注:也可以添加参数作为被删除的字符串,也就是说可以利用这3中方法删除原始字符串前后的任意指定字符串') ``` **分割字符串** split()用来分割字符串 splitlines()用来按行分割字符串 ```python #!/usr/bin/env python3.8 string = "a-b-c" string1 = "a---b---c" string2 = "hello,this is my first using of split,are you ok?yes,I am ok" print(string.split("-")) #可以指定单个分割符 print( string1.split("---")) #也可以指定多个字符当作分割符 print(string1.split("--")) print(string2.split(",",2)) #还可以指定分割符的最大使用次数,这里是只使用两次 ``` ```python string3 = "This is a multiline text" print (string3.split()) #不加参数,默认将空格当作分割符 string4 = '''This is a multiline piece of text''' print (string4.split()) #如果是多行文本,默认也是按空格分割 print (string4.splitlines()) #如果想按行分割,可以使用splitlines()方法 ``` Python的str类有split方法,但是这个split方法只能根据指定的某个字符分隔字符串,如果要同时指定多个字符来分隔字符串,该怎么办呢?幸运的是python的re模块中提供的split方法可以用来做这件事情 ``` import re re.split('; |, ',str) ``` 例如: ```python >>> a='Beautiful, is; better*than\nugly' >>> import re >>> re.split('; |, |\*|\n',a) ['Beautiful', 'is', 'better', 'than', 'ugly'] ``` **拼接字符串** 方法很多,其中join()方法性能最好,只是注意join处理的是列表 ```python #!/usr/bin/env python3.8 somelist = ['one','two','three','four'] print (','.join(somelist) ) #使用方法前面指定的分割符连接列表元素 print (', '.join(somelist)) print ('\t'.join(somelist)) print (''.join(somelist) ) # 注意:join()是字符串方法,如果你给他的参数是一串数字会报错! numlist = [1,2,3,4,5] # print ','.join(numlist) //这种方式直接会报错 # 可以使用下面的方式转换数字为字符串 print (','.join([str(i) for i in numlist])) # 列表表达式 print (','.join(str(i) for i in numlist)) ``` **取26个英文字母** ```python In [9]: string.ascii_lowercase Out[9]: 'abcdefghijklmnopqrstuvwxyz' ``` **中文内容处理** 注:python3不用处理即可使用 如果文件内容是中文: read方法读出来之后是16进制方式,需要用print打印 如果使用readlines读文件,文件内容会被放到列表里,想显示中文必须使用for循环print列表元素才能显示中文 比如: ```python [root@wing python]# cat a.txt 中文 la In [62]: f=open('a.txt','r') In [63]: content=f.readlines() In [64]: content Out[64]: ['中文\n'] In [65]: for i in content: ....: print (i) ....: 中文 ``` 替换字符 ```python str.maketrans 生成映射 str.translate 替换字符 >>> str="abcdefg" >>> str.translate(str.maketrans("abcd","1234")) '1234efg' ``` ---------------------------- shell相关字符串处理 用sed作文本的大小写替换 ```bash # sed 's/[a-z]/\u&/g' /etc/passwd # sed 's/[A-Z]/\l&/g' a ``` 删除文件倒数第二行: ```bash # sed '{N;$!P;D}' a.txt ``` 翻转文本内容: ```bash # tac a.txt ``` 大小写替换 ```bash # echo HEllo Word | tr a-z A-Z HELLO WORLD ``` 使用shell命令翻转字符串 ```bash # a=abcdefg # echo $a | rev gfedcba ``` ---------------------- ## 三、列表 打印一个产品信息的界面 ​ 欢迎来到千锋饮料售卖机 ​ 产品列表 ​ 名字 剩余量 单价 ​ 购买 ​ 上货 [![file://C:\Users\86186\AppData\Local\Temp\.A5M1Q0\1.png](assets/1.png)]() **序列** 序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推,Python已经内置确定序列的长度以及确定最大和最小的元素的方法。Python有6个序列的内置类型,最常见的是列表和元组。 **序列操作包括** 索引,切片,加,乘,检查成员 **列表** ​ 与 [immutable](https://docs.python.org/zh-cn/3.12/glossary.html#term-immutable) 字符串不同, 列表是 [mutable](https://docs.python.org/zh-cn/3.12/glossary.html#term-mutable) 类型,其内容可以改变 ​ 支持字符,数字,字符串甚至可以包含列表(嵌套),他的数据项不需要具有相同的类型 **创建列表** 以逗号分隔的不同的数据项使用方括号括起来即可。 例如: ```python list1 = ['physics', 'chemistry', 1997, 2000] list2 = [1, 2, 3, 4, 5 ] list3 = ["a", "b", "c", "d"] list4 = [] #创建空列表 list5 = list() #创建空列表 ``` **列表截取** 语法:变量[头下标:尾下标] 从左到右索引默认0开始的,从右到左索引默认-1开始,下标可以为空,表示取到头或尾。 例1: ```python #!/usr/bin/python3.8 list1 = ['physics', 'chemistry', 1997, 2000]; list2 = [1, 2, 3, 4, 5, 6, 7 ]; print("list1[0]: ", list1[0]) print("list2[1:5]: ", list2[1:5]) 以上实例输出结果: list1[0]: physics list2[1:5]: [2, 3, 4, 5] ``` 例2: ```python L = ['spam', 'Spam', 'SPAM!'] ``` 操作: | Python 表达式 | 结果 | 描述 | | ------------- | ----------------- | ------------------------ | | L[2] | 'SPAM!' | 读取列表中第三个元素 | | L[-2] | 'Spam' | 读取列表中倒数第二个元素 | | L[1:] | ['Spam', 'SPAM!'] | 从第二个元素开始截取列表 | **更新列表** 可以对列表的数据项进行修改或更新,也可以使用append()方法来添加列表项 例如: ```python #!/usr/bin/python list = ['physics', 'chemistry', 1997, 2000]; print ("Value available at index 2 : ") print (list[2]) list[2] = 2001 #更新列表元素 print ("New value available at index 2 : ") print (list[2]) 以上实例输出结果: Value available at index 2 : 1997 New value available at index 2 : 2001 ``` **删除列表元素** 使用 del 语句来删除列表的的元素 例 ```python #!/usr/bin/python3.8 list1 = ['physics', 'chemistry', 1997, 2000] print (list1) del list1[2] print ("After deleting value at index 2 : ") print (list1) 以上实例输出结果: ['physics', 'chemistry', 1997, 2000] After deleting value at index 2 : ['physics', 'chemistry', 2000] ``` **列表操作符** \+ 号用于组合列表 \* 号用于重复列表 in 判断元素是否在列表中 not in 例: | Python 表达式 | 结果 | 描述 | | ---------------------------- | ---------------------------- | -------------------- | | [1, 2, 3] + [4, 5, 6] | [1, 2, 3, 4, 5, 6] | 组合 | | ['Hi!'] * 4 | ['Hi!', 'Hi!', 'Hi!', 'Hi!'] | 重复 | | 3 in [1, 2, 3] | True | 元素是否存在于列表中 | | for x in [1, 2, 3]: print x, | 1 2 3 | 迭代 | 成员运算符可以使用for完成对列表的迭代,要按索引迭代序列,可以组合使用 [`range()`](https://docs.python.org/zh-cn/3.12/library/stdtypes.html#range) 和 [`len()`](https://docs.python.org/zh-cn/3.12/library/functions.html#len): ```python >>> a = ['Mary', 'had', 'a', 'little', 'lamb'] >>> for i in range(len(a)): ... print(i, a[i]) 0 Mary 1 had 2 a 3 little 4 lamb ``` 或者自定义计数器 ```python iterable=['a','b','c'] i = 0 for item in iterable: print(i, item) i += 1 ``` 不过大多数情况下 [`enumerate()`](https://docs.python.org/zh-cn/3.12/library/functions.html#enumerate) 函数很方便 **内置函数enumrate()** 为一个可迭代的对象添加序号,可迭代的对象你可以理解成能用for循环的就是可迭代的。 默认是编号是从0开始,可以设置从1开始 ```python iterable=['a','b','c'] for i, item in enumerate(iterable): print(i, item) ``` ```python 函数接收一个参数:默认是从0开始 >>> list(enumerate('abc')) (0, 'a') (1, 'b') (2, 'c') 函数接收第二个参数指定开始的数字: >>> enumerate('abc', 1) (1, 'a') (2, 'b') (3, 'c') ``` 实例: ```python #cat test.py li = ["手机", "电脑", '鼠标垫', '游艇'] for k, i in enumerate(li,1): # 这里的1表示序号从1开始 print(k,i) 执行结果如下: 1 手机 2 电脑 3 鼠标垫 4 游艇 ``` **逆向循环** 为了逆向对序列进行循环,可以求出欲循环的正向序列,然后调用 [`reversed()`](https://docs.python.org/zh-cn/3.12/library/functions.html#reversed) 函数: ```python >>> for i in reversed(range(1, 10, 2)): ... print(i) 9 7 5 3 1 ``` **排序** 按顺序循环序列,可以用 [`sorted()`](https://docs.python.org/zh-cn/3.12/library/functions.html#sorted) 函数,在不改动原序列的基础上,返回一个新的序列: ```python >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> for i in sorted(basket): ... print(i) apple apple banana orange orange pear ``` **列表方法** | 方法 | | ------------------------------------------------------------ | | list.append(obj) 在列表末尾添加新的对象 | | list.count(obj) 统计某个元素在列表中出现的次数 | | list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) | | list.index(obj) 从列表中找出某个值第一个匹配项的索引位置 | | list.insert(index, obj) 将对象插入列表 | | list.pop(obj=list[-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 | | list.remove(obj) 移除列表中某个值的第一个匹配项 | | list.reverse() 反向列表中元素 | | list.sort([func]) 对原列表进行排序 | operator.eq(a,b) 判断两个对象是否相等 ,使用之前import operator **给列表插入数据的其他方法** 把被切片出来的数据替换成后面的数据 ```python In [216]: a=['a', 'b', 'c', 'd', 'e'] In [215]: a[1:4] Out[215]: ['b', 'c', 'd'] In [217]: a[1:4]=[1] In [218]: a Out[218]: ['a', 1, 'e'] ``` 在索引为1的数据之前添加后面的数据 ``` In [224]: a[1:1]=[5] In [225]: a Out[225]: ['a', 5, 'b', 'c', 'd', 'e'] ``` 批量替换 ```python In [4]: a=[12, 3, 8, 8, 4, 3] In [5]: a[2:]=[1,1,1,] In [6]: a Out[6]: [12, 3, 1, 1, 1] ``` 另类删除: ```python In [7]: a=[12,3,4,3] In [8]: a[2:]=[] In [9]: a Out[9]: [12, 3] ``` 列表中嵌套列表: ```python >>> a=[1,2,['a','b']] >>> a [1, 2, ['a', 'b']] >>> a[2] ['a', 'b'] >>> a[2][0] 'a' >>> a[2][1] 'b' ``` 判断一个对象是否是一个列表(tuple,str,dict): ```python >>> test=[1,2,3] >>> isinstance(test,list) True ``` 变量解包:(可以用元组,列表,字典解包) ```python >>> l1,l2 = [[1,'x','y'],[2,'z','r']] >>> print(l1) [1, 'x', 'y'] >>> print(l2) [2, 'z', 'r'] ``` **列表解包** ```python In [59]: li=[1,2,3,4] In [60]: print(*li) 1 2 3 4 ``` 如果不采用解包的方法: ```python In [18]: a=[1, 2, 3, 4] In [19]: for i in a: ...: print(i,end=" ") ...: 1 2 3 4 ``` **slice() 函数** 实现切片对象,主要用在切片操作函数里的参数传递 语法: class slice(stop) class slice(start, stop[, step]) 参数说明: start -- 起始位置 stop -- 结束位置 step -- 间距 返回值 返回一个切片对象。 实例 ```python >>> myslice = slice(5) # 设置截取5个元素的切片 >>> myslice slice(None, 5, None) >>> arr = range(10) >>> arr [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> arr[myslice] # 截取 5 个元素 [0, 1, 2, 3, 4] ``` **浅拷贝** 用等号将一个列表赋值给多个变量时,使用其中任意一个变量对列表的操作,结果都会同步到其他变量的值。 ```python In [335]: a=b=[1,2,3] In [336]: a Out[336]: [1, 2, 3] In [337]: b Out[337]: [1, 2, 3] In [338]: a[1]=8 In [339]: a Out[339]: [1, 8, 3] In [340]: b Out[340]: [1, 8, 3] ``` 这种现象很像前面学的变量赋值,变量和列表本身之间的关系称作:变量对列表对象的引用并没有创建一个新的列表。 ```python In [110]: base_count = ['name',['money',100.00]] In [111]: xmen = list(base_count) In [112]: xpan = base_count.copy() # 浅复制 In [113]: xmen[1][1] = 20.00 In [114]: xpan Out[114]: ['name', ['money', 20.0]] ``` **深拷贝** ```python In [115]: import copy In [116]: xmen_new = copy.deepcopy(base_count) # 深复制 In [117]: xpan_new = copy.deepcopy(base_count) In [118]: xpan_new[1][1] = 50.00 In [119]: xmen_new Out[119]: ['name', ['money', 20.0]] In [120]: xpan_new Out[120]: ['name', ['money', 50.0]] ``` **pprint和pformat** pprint模块中使用的格式化可以按照一种格式正确的显示数据, 这种格式即可被解析器解析, 又很易读. **比如下面sys.path默认输出为:** 注意:ipython内自带优化看不出效果,需用自带python测试 ```python >>> import sys,pprint >>> sys.path ['', '/usr/lib/python2.7/site-packages/TimeConvert-1.4.0-py2.7.egg', '/usr/lib/ python2.7/site-packages/tzlocal-1.3-py2.7.egg', '/usr/lib64/python27.zip', '/usr/ lib64/python2.7', '/usr/lib64/python2.7/plat-linux2', '/usr/lib64/python2.7/lib-tk', '/ usr/lib64/python2.7/lib-old', '/usr/lib64/python2.7/lib-dynload', '/usr/lib64/ python2.7/site-packages', '/usr/lib64/python2.7/site-packages/gtk-2.0', '/usr/lib/ python2.7/site-packages'] ``` **用pprint方法会更易读** ```python >>> pprint.pprint(sys.path) ['', '/usr/lib/python2.7/site-packages/TimeConvert-1.4.0-py2.7.egg', '/usr/lib/python2.7/site-packages/tzlocal-1.3-py2.7.egg', '/usr/lib64/python27.zip', '/usr/lib64/python2.7', '/usr/lib64/python2.7/plat-linux2', '/usr/lib64/python2.7/lib-tk', '/usr/lib64/python2.7/lib-old', '/usr/lib64/python2.7/lib-dynload', '/usr/lib64/python2.7/site-packages', '/usr/lib64/python2.7/site-packages/gtk-2.0', '/usr/lib/python2.7/site-packages'] ``` 如果仅仅想获得数据而不是输出数据也可以用pformat ```python import sys import pprint str = pprint.pformat(sys.path) print(str) 运行结果同上 ``` ## 四、元组 **导语** 元组介绍 访问元组 修改元组 删除元组 元组运算符 元组索引、截取 无关闭分隔符 元组内置函数 **元组介绍** **使用元组的理由** ```ini 1. 占用内存空间小 2. 元组内的值不会被意外的修改 3. 可作为字典的键 4. 函数的参数是以元组形式传递的 5. 命名元组有时候可以代替类的对象(面向对象的时候讲) ``` ​ 与列表类似,不同之处在于元组的元素不能修改。 ​ 元组使用小括号,列表使用方括号。 ​ 元组的创建,只需要在括号中添加元素,并使用逗号隔开即可。 实例 ```python tup1 = ('physics', 'chemistry', 1997, 2000) tup2 = (1, 2, 3, 4, 5 ) tup3 = "a", "b", "c", "d" # 任意无符号的对象,以逗号隔开,默认为元组 var1,var2,var3,var4=tup3 # 元组解包(unpack),把元组中的元素分别赋值给前面的变量 ``` **创建空元组** ```python tup1 = () 元组中只包含一个元素时,需要在元素后面添加逗号,不加逗号会怎样,用type看一下类型 tup1 = (50,) ``` **访问元组** 元组与字符串类似,下标索引从0开始,可以进行截取,组合等 元组可以使用下标索引来访问元组中的值 实例: ```python #!/usr/bin/python3.8 tup1 = ('physics', 'chemistry', 1997, 2000); tup2 = (1, 2, 3, 4, 5, 6, 7 ); print("tup1[0]: ", tup1[0]) print("tup2[1:5]: ", tup2[1:5]) 输出结果: tup1[0]: physics tup2[1:5]: (2, 3, 4, 5) ``` **修改元组** 元组中的元素值不允许修改,但可以对元组进行连接组合 实例: ```python #!/usr/bin/python3.8 tup1 = (12, 34.56) tup2 = ('abc', 'xyz') # 以下修改元组元素操作是非法的。 # tup1[0] = 100; # 创建一个新的元组 tup3 = tup1 + tup2 print(tup3) 输出结果: (12, 34.56, 'abc', 'xyz') ``` **删除元组** 元组中的元素值是不允许删除的,但可使用del语句删除整个元组 实例: ```python #!/usr/bin/python3.8 tup = ('physics', 'chemistry', 1997, 2000) print (tup) del tup print ("After deleting tup : ") print (tup) # 以上实例元组被删除后,输出变量会有异常信息 输出结果: ('physics', 'chemistry', 1997, 2000) After deleting tup : Traceback (most recent call last): File "test.py", line 9, in print tup; NameError: name 'tup' is not defined ``` **元组解包** ```python In [199]: one,two = 1,2 In [200]: one,two = two,one In [201]: one Out[201]: 2 In [202]: two Out[202]: 1 ``` ## 五、字典 字典是**映射类型数据结构**,且可存储任意类型对象,是除列表以外python之中最灵活的内置数据结构类型。查找速度非常快,一个元素和10W个元素没有什么区别 • 在字典存放的每个元素都是以一对儿键值对。 • 在 Python 中字典通常被称为dict,键称为 key,值称为 value • 字典中不可以存在相同的 key,但是 value 可以。 **字典创建** 字典当中的元素是通过键来存取的,每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中。 格式:d = {key1 : value1, key2 : value2 } ```python dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'} dict1 = { 'abc': 456 } dict2 = { 'abc': 123, 98.6: 37 } dict3 = {} # 空字典 ``` **copy()创建字典** ```python a={"a":"b","aa":"bb"} b=a.copy() a= ``` **fromkeys()创建字典** 语法 dict.fromkeys(seq[, value]) seq -- 字典键值列表 value -- 可选参数, 设置键序列(seq)的值 以**序列** seq 中元素做字典的键,序列可以是字符串、列表、元组。value 为字典所有键对应的初始值。 实例 ```python #!/usr/bin/python3.8 seq = ('Google', 'Runoob', 'Taobao') dict = dict.fromkeys(seq) # dict = {}.fromkeys(seq) 也可以把dict写成{} print ("新字典为 : %s" % str(dict)) dict = dict.fromkeys(seq, 10) print ("新字典为 : %s" % str(dict)) 输出结果: 新字典为 : {'Google': None, 'Taobao': None, 'Runoob': None} 新字典为 : {'Google': 10, 'Taobao': 10, 'Runoob': 10} ``` **dict()创建字典** dict() 接收一个序列类型的参数,这个序列类型中的每个元素必须是成对出现 ```python >>>dict() # 创建空字典 {} >>> dict(a='a', b='b', t='t') # 传入关键字 {'a': 'a', 'b': 'b', 't': 't'} >>> dict([('one', 1), ('two', 2), ('three', 3)]) # 可迭代对象方式来构造字典 {'three': 3, 'two': 2, 'one': 1} # 字典的无序特性:列表是有序的对象结合,字典是无序的对象集合 ``` **zip()创建字典** 利用 zip() 函数**可以对具有相同数量的元素的序列进行配对**,返回的值不是元组,也不是列表,而是一个整合在一起的可迭代变量 ```python In [36]: english = 'Monday','Tuesday','Thursday', In [37]: chineses = '星期一','星期二','星期三' In [38]: zip(english,chineses) Out[38]: In [39]: type(zip(english,chineses)) Out[39]: zip In [27]: for key,value in zip(english,chineses): ...: print(key,value) Monday 星期一 Tuesday 星期二 Thursday 星期三 In [41]: list((english,chineses)) #转换成列表,这个的结果不能直接用dict转换 Out[41]: [('Monday', 'Tuesday', 'Thursday'), ('星期一', '星期二', '星期三')] In [40]: dict(zip(english,chineses)) # 映射函数方式来构造字典 Out[40]: {'Monday': '星期一', 'Thursday': '星期三', 'Tuesday': '星期二'} >>> dict(zip(['one', 'two', 'three'], [1, 2, 3])) # 映射函数方式来构造字典 {'three': 3, 'two': 2, 'one': 1} ==注意:zip() 函数会在最短序列迭代(循环)完毕时停止== ``` **key的唯一性和不可变性** **键** 必须是唯一且**不可变**的,如果同一个键被赋值两次,后一个值会被记住,**值** 则可以取**任何**数据类型 下面的字典最后长什么样子? ```python # python认为:True==1==1.0 d= {True:'yes',1:'no',1.0:'maybe'} print(d) ``` Python字典中的键 是否相同(只有相同才会覆盖)取决于两个条件: ```python 1、两者的值是否相等(比较__eq__()方法) 2、比较两者的哈希值是否相同(比较___hash__()hash方法) In [69]: (hash(True), hash(1), hash(1.0)) (1, 1, 1) ``` Python 内部用一个哈希表来维护字典中的 key 到 value 的映射关系 所以 key **必须是可哈希的**: 判断一个对象是否可哈希用hash()函数,返回一个整数,就是可哈希,反之会抛出 TypeError 异常 **python中可变数据类型有:** list dict set **python不可变数据类型:** 布尔型 整型 浮点型 元组 字符串 例如 ```python In [10]: li = [1,2,3,4] # 列表为可变类型 In [11]: dic = {'name':'wing','age':28,li:8} --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 dic = {'name':'wing','age':28,li:gender} TypeError: unhashable type: 'list' ``` **获取字典所有的 key** dict_obj.keys() ```python dic01={'a':1,'b':2} print(dic01.keys()) ``` **访问字典里的值**有三种方式: dict_obj['key'] # key 必须存在,不存在,抛出异常 ​ dict_obj.get('key') # key 存在获取到 value,不存在,返回 None ​ dict_obj.get('key', 'value') # key 不存在,返回指定的 value ```python #!/usr/bin/python3.8 dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} print ("dict['Name']: ", dict['Name']) print ("dict['Age']: ", dict['Age']) 输出结果: dict['Name']: Zara dict['Age']: 7 ``` **获取字典所有的 value** dict_obj.values() **一次性获取字典的 key 和 value** dict_obj.items() **两种遍历字典方法:** 第一种: ```python for k,v in dict.items(): print(k,v) ``` ​ 第二种:高效 ```python for key in dict: print(key,dict[key]) ``` **修改字典** 向字典添加新内容的方法是增加新的键/值对,修改或删除已有键/值对 ```python #!/usr/bin/python3.8 dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} dict['Age'] = 8 # update existing entry dict['School'] = "DPS School" # Add new entry print ("dict['Age']: ", dict['Age']) print("dict['School']: ", dict['School']) 输出结果: dict['Age']: 8 dict['School']: DPS School ``` **删除字典元素**: ```python del dict['Name'] # 删除键是'Name'的条目 dict.clear() # 清空字典所有条目 del dict # 删除字典 ``` **pop()** 截取字典key的value,源字典key会被删除 ```python In [361]: dic6 = {'b': 2, 'c': '3', 'd': 'new key', 'li': [1, 3, 5]} In [362]: dic6 Out[362]: {'b': 2, 'c': '3', 'd': 'new key', 'li': [1, 3, 5]} In [363]: li = dic6.pop('li') In [364]: li # 劫取出来的value Out[364]: [1, 3, 5] In [365]: dic6 Out[365]: {'b': 2, 'c': '3', 'd': 'new key'} ``` **字典相关内置函数** dict.setdefault(key, default=None) 和get()类似, 但如果key在字典中不存在,将会添加键并将值设为default,不管添加成功与否,都返回该key对应的value 也是给字典添加元素的一种方式 ```python In [85]: f Out[85]: {1: '农夫山泉', 2: '矿泉水', 3: '可乐'} In [83]: f.setdefault(8,"雪碧") Out[83]: '雪碧' ``` dict.update(dict2) 把字典dict2的键/值对更新到dict里 **字典变量解包** ```python >>> d3,d4 = {'x':32,'y':80} >>> print(d3) x >>> print(d4) y ``` **应用场景** ```python host_info = [] host_info.append( {'192.168.1.11': {'cpu':['Intel(R) Core(TM) i5-5350U CPU @ 1.80GHz',4,1], 'memory':['16','4','2'], 'disk':['1T','2T'] } } ) jso host_info.append({'192.168.1.12': {'cpu':['Intel(R) Core(TM) i5-5350U CPU @ 1.80GHz',4,1],'memory':['16','4','2'],'disk':['1T','2T']}}) host_info[0]["192.168.1.11"]['disk'][0] ``` ## 六、集合 集合就是数学里的集合,没有什么特殊的定义。集合最好的应用是去重。 表示方法是通过一个{}创建或者通过set和frozenset函数转换成集合。 **有两个函数可创建集合类型对象** ```python set() # 创建可变集合对象 frozenset() # 创建不可变集合对象 ``` **可变集合创建** ```python s = {"tom","cat","name","error"} # 或 s = set({"tom","cat","name","error"}) ``` **不可变集合创建**: ```python >>> s = [23,3,4,32] >>> d = frozenset(s) # 创建不可变集合d >>> print(d) frozenset({23,3,4,32}) ``` **集合特性** ​ 集合是一组无序可哈希(hash)的值,所有元素不会重复  支持成员关系测试:in , not in  支持迭代,集合中的元素必须是可迭代对象  不支持:索引、元素获取、切片  没有特定语法格式,只能通过工厂函数set或者frozenset创建,字符串则直接创建即可 注:可哈希是什么意思 hash是一种函数映射,称为hash函数,y=hash_func(x),可hash就是指对于一个对象x有其对应的y。在python内部是通过字典key的hash值来对应内存中的value地址的,所以两个相同hash的key就表示同一个了,而不可hash的对象自然也不能作为字典的key。 **集合运算符**: s | t s和t的并集 s & t s和t的交集 s - t 求差集 s ^ t 求对称差集 **适用于set可变集合常用方法**: s.add(item) 将item添加到s中。如果item已经在s中,则无任何效果 s.remove(item) 从s中删除item。如果item不是s的成员,则引发KeyError异常 s.discard(item) 从s中删除item。如果item不是s的成员,则无任何效果 s.pop() 随机删除一个s中任意的集合元素,如果有变量接收则会接收到删除到的那个元素 s.clear() 删除s中的所有元素 s.copy() 浅复制 s.update(t) 将t中的所有元素添加到s中。t可以是另一个集合、一个序列或者支持迭代的任意对象 s.union(t) 并集。返回所有在s和t中的元素 s.intersection(t) 交集。返回所有同时在s和t中的都有的元素 s.intersection_update(t) 算s与t的交集,并将结果赋值给s s.difference(t) 差集。返回所有在set中,但不在t中的元素 s.difference_update(t) 从s中删除同时也在t中的所有元素 s.symmetric_difference(t) 求对称差集。返回所有s中没有t中的元素和t中没有s中的元素组成的集合 s.sysmmetric_difference_update(t) 计算s与t的对称差集,并将结果放入s s.isdisjoint(t) 如果s和t没有相同项,则返回True s.issubset(t) 如果s是t的一个子集,则返回True s.issuperset(t) 如果s是t的一个超集,则返回True **集合实例:祛除列表中重复的元素** 例1:去除海量列表里重复元素 ```python >>> a = [11,22,33,44,11,22] >>> b = set(a) >>> b set([33, 11, 44, 22]) ``` 例2:去除重复元素后转换成列表 ```python l1 = ['b','c','d','b','c','a','a'] l2 = list(set(l1)) print(l2) ``` 还有一种 ```python l1 = ['b','c','d','b','c','a','a'] l2 = {}.fromkeys(l1).keys() l3=[] for i in l2: l3.append(i) print(l3) ``` 这两种都有个缺点,祛除重复元素后排序变了: ['a', 'c', 'b', 'd'] 如果想要保持他们原来的排序:用list类的sort方法 ```python l1 = ['b','c','d','b','c','a','a'] l2 = list(set(l1)) l2.sort(key=l1.index) print(l2) ``` 也可以这样写: ```python l1 = ['b','c','d','b','c','a','a'] l2 = sorted(set(l1),key=l1.index) print(l2) ``` 也可以用遍历: ```python l1 = ['b','c','d','b','c','a','a'] l2 = [] for i in l1: if not i in l2: l2.append(i) print(l2) ``` 上面的代码也可以这样写 ```python l1 = ['b','c','d','b','c','a','a'] l2 = [] [l2.append(i) for i in l1 if not i in l2] # 列表推导式 print l2 ``` 这样就可以保证排序不变了 ['b', 'c', 'd', 'a'] **None类型** ```python In [66]: a=None In [67]: type(None) NoneType ``` ## 七、内建函数 查看系统内所有内置函数(BIF):isinstance就在里面 ```python >>> dir(__builtins__) ``` **长度、最大最小值** 支持字符串、列表、元组、字典、集合,不支持数字 ```python len(str) 字符串长度 In [11]: a='hello world' In [15]: len(a) Out[15]: 11 ``` ```python max(str) 返回字符串 str 中最大的字母。 In [42]: max(a) Out[42]: 'w' min(str) 返回字符串 str 中最小的字母。 In [45]: min(a) Out[45]: ' ' ``` **类型转换** 数据类型的转换,你只需要将数据类型作为函数名即可。 以下几个内置的函数可以执行数据类型之间的转换。这些函数返回一个新的对象,表示转换的值。 | 函数 | 意义 | | ------------ | ------------------------------------------------------------ | | float(x) | print(float('10')) 将x转换到一个浮点数 | | **str(x)** | print(str(10)) 将x转换为字符串 | | repr(x) | print(type(repr(10))) 将对象 x 转换为表达式字符串 | | eval(str) | print(eval('5+8')) 用来计算在字符串中的有效Python表达式,并返回一个对象 | | **tuple(s)** | 将序列 s 转换为一个元组 | | **list(s)** | 将序列 s 转换为一个列表 | | **set(s)** | 转换为可变集合 | | **dict(d)** | 创建一个字典。d 必须是一个序列 (key,value)元组。成对出现的数据,比如a=8,b=9 | | frozenset(s) | 转换为不可变集合 | | **int(d)** | 转换为整型 | | chr(x) | asc=chr(97);print(asc) 将一个整数转换为一个字符,ascii与字符的转换函数 | | ord(x) | asc=ord('a');print(asc) 将一个字符转换为它的整数值,与chr()相反 | | hex(x) | asc=hex(10);print(asc) 将一个整数转换为一个十六进制字符串 | | oct(x) | asc=oct(10);print(asc) 将一个整数转换为一个八进制字符串 | **常用的几个** int list tuple str dict **str与repr的区别** ​ str()一般是将数值转成字符串(返回一个字符串,包含对象的友好的可打印表示形式。对于字符串,它返回字符串本身)。 ​ '' 输出本身内容 ​ repr()是将一个对象转成字符串显示。 ​ 实质上''与repr()意义是相同的。 **eval函数类型转换**   功能:将字符串str当成有效的表达式来求值并返回计算结果。   语法: eval(source[, globals[, locals]]) -> value   参数:     source:一个Python表达式或函数compile()返回的代码对象     globals:可选。必须是dictionary     locals:可选。任意map对象 ```python 1 可以把list,tuple,dict和string相互转化。 2 ################################################# 3 字符串转换成列表 4 >>>a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]" 5 >>>type(a) 6 7 >>> b = eval(a) 8 >>> print b 9 [[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]] 10 >>> type(b) 11 12 ################################################# 13 字符串转换成字典 14 >>> a = "{1: 'a', 2: 'b'}" 15 >>> type(a) 16 17 >>> b = eval(a) 18 >>> print b 19 {1: 'a', 2: 'b'} 20 >>> type(b) 21 22 ################################################# 23 字符串转换成元组 24 >>> a = "([1,2], [3,4], [5,6], [7,8], (9,0))" 25 >>> type(a) 26 27 >>> b = eval(a) 28 >>> print b 29 ([1, 2], [3, 4], [5, 6], [7, 8], (9, 0)) 30 >>> type(b) 31 ``` ## 八、推导式 推导式是 Python 语言中独有的特性,它是从一个或者多个迭代器快速简洁地创建数据结构的一种方法,可以将循环和条件判断相结合,从而避免语法冗长的代码 **列表推导式** list comprehension -- 列表推导式,处理一个序列中的所有或部分元素并返回结果列表的一种紧凑写法。 ```python # 语法格式 [expression for item in iterable ] expression # 表达式,比如 单独的变量名,变量名 - 1 item # 循环变量 iterable # 可迭代对象 其后面可以跟判断条件,如: [expression for item in iterable if condition] ``` ```python # 传统方法 In [1]: number_list = list(range(1,5)) In [2]: number_list Out[2]: [1, 2, 3, 4] # 列表推导式 In [3]: num_list = [n for n in range(1,7)] In [4]: num_list Out[4]: [1, 2, 3, 4, 5, 6] ``` ```python [i for i in 1,2,3,4] # 报错 [i for i in (1,2,3,4)] # 正确 ``` ```python # 添加有表达式的列表推导式 In [5]: num_list = [n - 1 for n in range(1,7)] In [6]: num_list Out[6]: [0, 1, 2, 3, 4, 5] ``` ```python # 有条件判断的传统方法 In [7]: a_list = [] In [8]: for n in range(1,6): ...: if n % 2 == 1: ...: a_list.append(n) ...: In [9]: a_list Out[9]: [1, 3, 5] # 有条件判断的列表推导式 In [10]: a_list = [n for n in range(1,6) if n % 2 == 1] In [11]: a_list Out[11]: [1, 3, 5] ``` ```python # 含有嵌套循环的一般方法 In [12]: rows = range(1,4) In [13]: cols = range(1,3) In [14]: for row in rows: ...: for col in cols: ...: print(row,col) ...: 1 1 1 2 2 1 2 2 3 1 3 2 # 含有嵌套循环的列表推导式 In [15]: rows = range(1,4) In [16]: cols = range(1,3) In [17]: cells = [(row,col) for row in rows for col in cols] In [18]: for cell in cells: ...: print(cell) ...: (1, 1) (1, 2) (2, 1) (2, 2) (3, 1) (3, 2) ``` **字典推导式** ```python {key_expression:value_expression for expression in iterable} ``` ```python # 一个简单的例子 words = 'letters' w_counts = {w: words.count(w) for w in words} print(w_counts) ``` ```python # 利用 set 集合去重,以减少 words.count(letter) 的次数,以节约资源和时间 w_counts = {w: words.count(w) for w in set(words)} ``` **集合推导式** 格式和列表、字典推导式的格式一样 ```python >>> a_set = {n for n in range(1,6) if n % 3 == 1} >>> a_set {1, 4} ``` **生成器推导式** ​ 也许机智的你已经发现了以上的规律,如果将列表推导式的方括号变成圆括号就可以定义一个元组推导式; ​ 不幸的是,元组没有推导式,其实它是一个生成器推导式,它返回的是一个生成器对象,可以直接对其进行迭代。 ​ **特点:** ​ 一个生成器只能运行一次。list/set/str/dict 都是存储在内存里的,但生成器仅在运行时产生值,不会被保存下来,当然也不能对其备份。 ```python >>> number_thing = (number for number in range(1,6) if number % 2 == 1) >>> number_thing at 0x7f25d59f1820> >>> type(number_thing) # 可以直接对生成器对象进行迭代 >>> for number in number_thing: ... print(number) ... 1 3 5 # 可以对其调用 list()函数,但是由于上面已经迭代一次了,由于其是无法保存的,所以再次进行迭代,发现它已经不存在了 >>> list(number_thing) [] # 再次生成 >>> number_thing = (number for number in range(1,6) if number % 2 == 1) >>> list(number_thing) [1, 3, 5] ``` ​