文章内容
2017/9/22 11:05:23,作 者: 黄兵
列表、元组和字符串(二)
接着上一节继续: reverse()方法的作用是将整个列表原地翻转,解释一下就是原来是从小到大的排序,使用reverse()方法就从大到小排序了。看一下例子:
>>> list1 = [1,2,3,4,5,6]
>>> list1.reverse()
>>> list1
[6, 5, 4, 3, 2, 1]
sort()方法是用指定的方法对列表进行排序,默认不需要参数,从小到大排序:
>>> list1=[5,3,7,2,4,3,8]
>>> list1.sort()
>>> list1
[2, 3, 3, 4, 5, 7, 8]
看到这个的时候有如果说给你一个列表,让葱大到小排序,你一定说用sort()方法从小到大排序,然后用reverse()方法进行翻转。这样写也没错,只是有点太麻烦,下面就说一个简单的。
sort()方法其实默认有三个参数,其形式是:sort(func, key, reverse)。func和key用于设置排序的算法和关键字,默认是使用归并排序,算法问题后面在说。这里就说一下sort()方法的第三个参数reverse,这个就是reverse()的方法,默认是sort(reverse=False)表示不颠倒顺序,如果把False改成True就会翻转,看下面的例子:
>>> list1=[5,3,7,2,4,3,8]
>>> list1.sort(reverse=False)
>>> list1
[2, 3, 3, 4, 5, 7, 8]
>>> list1.sort(reverse=True)
>>> list1
[8, 7, 5, 4, 3, 3, 2]
1.9 关于分片“拷贝”概念的补充
上节在列表分片中说过一段分片,下面看一下:
>>> list1 = [5,3,7,2,4,8]
>>> list2=list1[:]
>>> list2
[5, 3, 7, 2, 4, 8]
>>> list3 = list1
>>> list3
[5, 3, 7, 2, 4, 8]
用列表分片后给另一个列表看似三个列表一样吧,如果我修改一个列表看一下其他列表会怎么样:
>>> list1.sort(reverse=True)
>>> list1
[8, 7, 5, 4, 3, 2]
>>> list2
[5, 3, 7, 2, 4, 8]
>>> list3
[8, 7, 5, 4, 3, 2]
当改变list1的时候list3也发生了改变,不过list2没有改变,这就需要我们回忆一下在说变量的时候说过,Python的变量是一个标签,只是一个名字而已。看一下下面的示意图
根据示意图可以看出为了一个列表指定另一个名字的做法,只是向同一个列表增加新的标签而已,真正的拷贝是要使用分片的方法,这个也是刚学的时候最容易混淆的地方。
2 元组:戴上了枷锁的列表
由于Python中的列表功能过于强大,所以才有了列表的“表亲”元组,列表和元组的最大区别就是可以修改元素,插入元素,删除元素。而元组不可以,像字符串一样不能改变,当然也不能排序了,
>>> tuple1 = (2,1,3,7,5,9)
>>> tuple1
(2, 1, 3, 7, 5, 9)
访问元组和列表是一样的:
>>> tuple1[3]
7
>>> tuple1[1:4]
(1, 3, 7)
>>> tuple1[1:]
(1, 3, 7, 5, 9)
>>> tuple1[:4]
(2, 1, 3, 7)
也可以使用分片复制一个元组:
>>> tuple2=tuple1[3:]
>>> tuple2
(7, 5, 9)
如果说我一定要修改元组像列表一样,哪肯定会报错:
>>> tuple1[0]=1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
如果说列表的标志就是中括号([]),那么元组的标志是什么,你不能说是小括号(()),可以看一下下面的例子:
>>> tuple1 = 1,2,3,4
>>> type(tuple1)
<class 'tuple'>
前面有说过type()方法是返回参数的类型,这里返回的是tuple,这里没有加括号一样也是元组。
>>> tuple1 = (1)
>>> type(tuple1)
<class 'int'>
加了一个括号反而不是元组了,为什么?可以对比一下的区别是在于没有逗号,这里的逗号才是最关键的,而小括号只是一个补充的作用,如果创建一个空的元组,直接用小括号就好了。
>>> tuple1 = ()
>>> type(tuple1)
<class 'tuple'>
这里要注意的是,如果创建的元组中只有一个元素,哪就在元素后面在一个逗号,这样就告诉Python,你创建的是一个元组,而不是整数或者浮点数什么的。
>>> tuple1 = (2)
>>> type(tuple1)
<class 'int'>
>>> tuple1 = (2,)
>>> type(tuple1)
<class 'tuple'>
>>> tuple1 = 2
>>> type(tuple1)
<class 'int'>
>>> tuple1 = 2,
>>> type(tuple1)
<class 'tuple'>
为了证明逗号的作用,看一下下面这个例子:
>>> 3 * (3)
9
>>> 3 * (3,)
(3, 3, 3)
2.2 更新和删除元组
前面已经说过元组是不能修改,插入,删除的。这里又说更新和删除,然而这些并不矛盾,我们可以根据字符串的分片来用到元组中,看一下下面的例子:
>>> temp = ('hello', 'Pythonv3')
>>> temp = temp[:1] + ('word',) + temp[1:]
>>> temp
('hello', 'word', 'Pythonv3')
通过分片让元组拆分两个部分,然后用(+)合并组成一个新的元组,然后把原来的变量名指向新的元组,在组合的过程中中间的小括号是必须要加的。这里要说一下只能使用分片,不能直接用元素,可以看下面的例子:
>>> temp = ('hello', 'Pythonv3')
>>> temp = temp[0] + ('word',) + temp[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'tuple' object to str implicitly
列表有三个删除元素的方法分别是:remove(),del(),pop()。然而,对于元组缺一个也没有,不过我们可以根据上面的切分组合,看下面的例子:
>>> temp = ('Hello', 'Word', 'Pythonv3')
>>> temp = temp[:1] + temp[2:]
>>> temp
('Hello', 'Pythonv3')
如果删除整个元组可以使用del,
>>> del temp
>>> temp
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'temp' is not defined
不过这个在开发的过程中很少用,因为Python自己有一个回收机制,可以在不使用的时候自动删除。
总结:操作符可以用在元组上,拼接操作符和重复操作符上面已经举例,关系操作符,逻辑操作符和成员关系操作符in和not in也可以直接用在元组上,这和列表是一样的。
3 字符串
前面说了列表和元组,下面说一下字符串,字符串也可以用到分片,看下面的例子:
>>> str = 'I Love Python3v'
>>> str[:6]
'I Love'
在Python中没有字符这个类型,所以如果想访问字符串中的字符,可以使用索引和列表,元组的方法一样来索引字符串:
>>> str = 'I Love Python3v'
>>> str[7:15]
'Python3v'
>>> str[7]
'P'
>>> str[7:]
'Python3v'
字符串和元组是一样的,都是不能更新和删除。如果非要这样可以使用分片和元组一样。
>>> str = 'Hello Python3v Word'
>>> str = str[:5] + str[14:]
>>> str
'Hello Word
这里要注意一下,通过旧字符串的拼接得到一个新的字符串的方式并不是真的改变了原始字符串,原来的字符串还在,只是指向了新的字符串(旧的字符串一旦失去作用就会被Python垃圾回收机制释放)。
3.1 各种内置方法
下面是字符串的内置方法:
符 号 | 含 义 |
---|---|
capitalize() | 把字符串的第一个字符改为大写 |
casefold() | 把整个字符串的所有字符改为小写 |
center(width) | 将字符串居中,并使用空格填充至长度width的新字符串 |
count() | 返回sub在字符串里出现的次数,start和end参数表示范围,可选 |
encode(encoding='utf-8',errors='strict') | 以encoding指定的编码格式对字符串进行编码 |
endswith(sub[, start[, end]]) | 检查字符串是否以sub字符串结束,如果是返回True,否则返回False,start和end参数表示范围,可选 |
expandtabs([tabsize=8]) | 把字符串中的tab符号(\t)转换为空格,如不指定参数,默认的空格数是 tabsize=8 |
find ( , start , end ) | 检测sub是否包含在字符串中,如果有则返回索引值,否则返回-一1,start和end参数表示范围,可选 |
index(sub[,start[,end]]) | 跟find方法一样,不过如果sub不在string中会产生一个异常 |
isalnumo() | 如果字符串至少有一个字符并且所有字符都是字母或数字则返回True,否则返回False |
isalpha () | 如果字符串至少有一个字符并且所有字符都是字母则返回True,否则返回False |
isdecimalo() | 如果字符串只包含十进制数字则返回True,否则返回False |
isdigit() | 如果字符串只包含数字则返回True,否则返回 False |
islower() | 如果字符串中至少包含一个区分大小写的字符,并且这些字符都是小写,则返回True,否则返回False |
isnumeric() | 如果字符串中只包含数字字符,则返回True,否则返回False |
isspace() | 如果字符串中只包含空格,则返回True,否则返回False |
istitle() | 如果字符串是标题化(所有的单词都是以大写开始,其余字母均小写),则返回True,否则返回False |
isupper() | 如果字符串中至少包含一个区分大小写的字符,并且这些字符都是大写,则返回True,否则返回False |
Join(sub) | 以字符串作为分隔符,插入到sub中所有的字符之间 |
ljust(width) | 返回一个左对齐的字符串,并使用空格填充至长度为width的新字符串 |
lower() | 转换字符串中所有大写字符为小写 |
Istrip() | 去掉字符串左边的所有空格 |
partition(sub) | 找到子字符串sub,把字符串分成一个3元组( presub,sub, folsub),如果字符串中不包含sub则返回('原字符串','',") |
replace(old newl[, count]) | 把字符串中的old子字符串替换成new子字符串,如果count指定,则替换不超过count次 |
rfind (sub[, start[, end]]) | 类似于find()方法,不过是从右边开始查找 |
rindex(sub[, start[, end]]) | 类似于index()方法,不过是从右边开始查找 |
rjust(width) | 返回一个右对齐的字符串,并使用空格填充至长度为width的新字符串 |
rpartition(sub) | 类似于partition()方法,不过是从右边开始查找 |
rstrip() | 删除字符串末尾的空格 |
split(sep=None, maxsplit=-1) | 不带参数默认是以空格为分隔符切片字符串,如果maxsplit参数有设置,则仅分隔maxsplit个子字符串,返回切片后的子字符串拼接的列表 |
splitlines([keepends]) | 按照'\n'分隔,返回一个包含各行作为元素的列表,如果keepends参数指定,则返回前keepends行 |
startswith(prefix[, start[, end]]) | 检查字符串是否以prefix开头,是则返回True,否则返回 False . start和end参数可以指定范围检查,可选 |
strip([chars]) | 删除字符串前边和后边所有的空格, chars参数可以定制删除的字符,可选 |
swapcase() | 翻转字符串中的大小写 |
title() | 返回标题化(所有的单词都是以大写开始,其余字母均小写)的字符串 |
translate(table) | 根据table的规则(可以由str, maketrans('a',"b')定制)转换字符串中的字符 |
upper() | 转换字符串中的所有小写字符为大写 |
zfill(width) | 返回长度为width的字符串,原字符串右对齐,前边用0填充。 |
这里给大家演示及格常用的,第一个casefold()方法,作用是将所有字符串中的所有字符串由大写变为小写。
>>> str1 = "Hello Word Python3v"
>>> str1.casefold()
'hello word python3v'
count(sub[, start[, end]])就是查找sub字符串出现的次数可选参数(注:Python文档中,用方括号[]括起来表示可选)start和end表示查找的范围。
>>> str1 = "AbcABCabCabcABCabc"
>>> str1.count('ab', 0, 15)
2
使用find(sub[, start[, end]])或index(sub[, start[, end]])方法,查找某个字符串在该字符串中的位置。如果找到了,则返回值是第一个字符的索引值,如果找不到,则find()方法会返回-1,而index()方法会抛出异常(注:异常是可以被捕获并处理的错误)
>>> str1 = "Hello Word Python3v"
>>> str1.find('Python3v')
11
>>> str1.find('python')
-1
>>> str1.index('Python3v')
11
>>> str1.index('python')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
很多时候程序员都会使用join(sub)以字符串作为分隔符,插入到sub字符串中所有的字符串之间:
>>> 'x'.join('hello')
'hxexlxlxo'
>>> '_'.join('Python3v')
'P_y_t_h_o_n_3_v'
连接符号(+)也可以连接字符串,但是如果数据量大的话,就会出现内存复制以及垃圾回收操作。所以对于大量的字符串拼接使用join()方法的效率比较高一点。
>>> 'Hello' + ' ' + 'Word' + ' ' + 'Python3v'
'Hello Word Python3v'
>>> ' '.join(['Hello','Word','Python3v'])
'Hello Word Python3v'
replace(old, new[, count])方法就是替换指定的字符串:
>>> str1 = 'I Love You'
>>> str1.replace('You','Python3v')
'I Love Python3v'
split(sep=None, maxsplit=-1)跟join()正好相反,split()用于拆分字符串:
>>> str1 = ' '.join(['Hello', 'Word', 'Python3v'])
>>> str1
'Hello Word Python3v'
>>> str1.split()
['Hello', 'Word', 'Python3v']
>>> str2=' '.join('Python3v')
>>> str2
'P y t h o n 3 v'
>>> str2.split(sep='_')
['P y t h o n 3 v']
>>> str2.split()
['P', 'y', 't', 'h', 'o', 'n', '3', 'v']
3.2 格式化
格式化字符串就是按照统一的规格去输出一个字符串,怎么理解呢?比如中国有36个民族,每个民族的方言都不一样,为了相互之间能过沟通,国家规定交流使用普通话,这样不管和任何少数民族交流,都是使用普通话作为翻译,如果没有一个统一,哪如果交流起来可能就有点费劲了。在比如十六进制的10和十进制的10或者二进制的2进行比较时不是要准换一下,然后才能进行比较,二格式化就是做这个用的。
3.2.1 format() 方法就是用来格式化的,它接受位置参数和关键字参数(位置参数和关键字参数在函数中有详细的讲解),两者都是传递到一个叫做replacement字段,而这个replacement字段在字符串内由大括号({})表示。先看一下下面的例子:
>>> "{0} Word {1}{2}".format('Hello','Python','3v')
'Hello Word Python3v'
字符串中的{0}、{1}、{2}分别是format()方法中参数的位置索引,被format()方法的三个参数替换,那么format()的三个参数就叫位置参数。关键字参数是什么呢?看一下下面的例子:
>>> "{a} Word {b}{c}".format(a='Hello',b='Python',c='3v')
'Hello Word Python3v'
{a},{b},{c}就相当于三个标签,format()将参数中等值的字符串替换进去,这就是位置关键参数,另外,也可以考虑综合位置参数和关键字参数一起使用。
>>> '{0} Word {b}{d}'.format('Hello',b='Python',d='3v')
'Hello Word Python3v'
>>> '{b} Word {0}{d}'.format('Hello',b='Python',d='3v')
'Python Word Hello3v'
>>> '{b} Word {d}{0}'.format('Hello',b='Python',d='3v')
'Python Word 3vHello'
如果综合使用必须将位置参数放在关键参数前面,要不就会出错了:
>>> '{b} Word {d}{0}'.format(d='Hello',b='Python','3v')
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
如果打印大括号需要用到转义符,跟字符串转义符一样这里用到的是加一层大括号即可(在字符串转义符(),只需要转义字符转义本身(\))
>>> '{{Word}}'.format('Python3v')
'{Word}'
位置参数'{Word}'没有打印是因为{Word}被外层的{}剥夺,因此没有输出,当然也没有报错了。下面看最后一个例子:
>>> '{0}: {1:.2f}'.format('圆周率', 3.14159)
'圆周率: 3.14'
这里位置参数{0}跟前面的例子不一样,后面加了个冒号,在替换域中,冒号表示格式化符号的开始,“.2”的意识是四舍五入到保留两位小数点,而{}的意思是定点数,所以按照格式化的要求打印了3.14.
3.2.2 格式化操作符:%
如何分辨%是否是余数的操作符还是格式化的操作符,就看两边的元素。如果两边是数字的时候,它就表示求余数;如果是字符串的时候,它就是格式化操作符。下面是Python的格式化符号以及含义:
格式化符号及含义
符 号 | 含 义 |
---|---|
%c | 格式化字符及其ASCII码 |
%s | 格式化字符串 |
%d | 格式化整数 |
%o | 格式化无符号八进制数 |
%x | 格式化无符号十六进制数 |
%X | 格式化无符号十六进制数(大写) |
%f | 格式化浮点数字,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 用作同%e,用科学计数法格式化浮点数 |
%g | 数值的大小决定使用%f或%e |
%G | 作用同g,数值的大小决定使用%f或%E |
下面说几个例子:
>>> '%c' % 97
'a'
>>> '%c%c%c%c%c%c%c%c' % (80,121,116,104,111,110,51,118)
'Python3v'
>>> '%d转换为八进制是: %o' % (123, 123)
'123转换为八进制是: 173'
>>> '%f用科学计数法表示为: %e' % (149500000,149500000)
'149500000.000000用科学计数法表示为: 1.495000e+08'
Python还提供格式化操作符的辅助指令
符 号 | 含 义 |
---|---|
m,n | m是显示最小总宽度,n是小数点后的位数 |
- | 结果是左对齐 |
+ | 在正数前面显示(+) |
# | 在八进制数前面显示‘0o’,在十六制数前面显示‘0x64’或‘0X64’ |
0 | 显示的数字前面填充‘0’代替空格 |
同样提供几个例子:
>>> '%5.1f' % 27.658
' 27.7'
>>> '%.2e' % 27.658
'2.77e+01'
>>> '%10d' % 5
' 5'
>>> '%1d' % 5
'5'
>>> '% -10d' % 5
' 5 '
>>> '%010d' % 5
'0000000005'
>>> '%#X' % 100
'0X64'
3.2.3 Python的转义字符及含义
转义字符及含义的总结
符 号 | 含 义 |
---|---|
\' | 单引号 |
\" | 双引号 |
\a | 发出系统响铃生 |
\b | 退格符 |
\n | 换行符 |
\t | 横向制表符(TAB) |
\v | 纵向制表符 |
\r | 回车符 |
\f | 换页符 |
\o | 八进制代表的字符 |
\x | 十六进制代表的字符 |
\0 | 表示一个空字符 |
\ | 反斜杠 |
4 序列
根据上面的内容你会发现列表、元组和字符串之间有很多共同点:
都可以通过索引得到一个元素
默认索引都是从0开始(也可以支持负数索引)
可以通过分片的方法得到一个范围内的元素集合
有很多共同点操作符(重复操作符、拼接操作符、成员关系操作符)
我们把这些共同点统称之为序列,下面说一下序列常用的BIF(内置方法)
4.1 list([iterable])
list()方法用于把一个迭代对象转换为列表,而迭代就是就是for循环的意思,重复反馈的过程,其目的是为了接近目标或者结果。每一次对过程的重复被称为一次“迭代”,而每一次迭代所得到的结果会被用作下一次迭代的初始值......
list()方法要么不带参数,要么带一个可迭代对象作为参数,而这个序列天生就是一个可迭代对象(迭代的概念实际上就是从序列中泛化而来),下面举几个例子吧:
>>> a = list() #创建一个空列表
>>> a
[]
>>> b = list('Python3v') #将字符串的每一个字符迭代存放到列表中
>>> b
['P', 'y', 't', 'h', 'o', 'n', '3', 'v']
>>> c = list((1,2,3,4,5)) #将元组中的每个元素迭代存放到列表中
>>> c
[1, 2, 3, 4, 5]
新建一个列表,然后循环通过索引参数到每一个元素并加入列表,迭代完毕后返回列表即可。
4.2 tuple([iterable])
tuple()方法是用于把一个可迭代对象转换为元组,具体到用法和list()一样,看一下例子:
>>> a = tuple()
>>> a
()
>>> b = tuple('Python3v')
>>> b
('P', 'y', 't', 'h', 'o', 'n', '3', 'v')
>>> c = tuple([1,2,3,4])
>>> c
(1, 2, 3, 4)
4.3 str(obj)
str(obj)方法用于把obj对象转换为字符串,这里简单的说几个例子:
>>> a = [1,2,3,4]
>>> b = str(a)
>>> type(b)
<class 'str'>
>>> b
'[1, 2, 3, 4]'
4.4 len(sub)
len()方法用于返回sub参数的长度:
>>> str1 = 'Python3v'
>>> len(str1)
8
>>> list1 = [1,2,3,4]
>>> len(list1)
4
>>> tuple1 = (1,2,3,4,5)
>>> len(tuple1)
5
4.5 max(...)
max()方法就是返回序列或者是参数中的最大值,也就是说max()的参数可以是一个序列,返回值是该序列中对大的值。
>>> str1 = 'Python3v'
>>> max(str1)
'y'
>>> list1 = [56,23,98,-56,43,78]
>>> max(list1)
98
>>> tuple1 = (31,92,33,74,45)
>>> max(tuple1)
92
4.6 min(...)
min()方法跟max()方法正好相反,返回的是最小值。这里要注意一下,max() 和min()的参数必须保证是一个序列或参数的数据类型必须一致,否则就会报错。
>>> str1 = 'Python3v'
>>> min(str1)
'3'
>>> list1 = [56,23,98,-56,43,78]
>>> min(list1)
-56
>>> tuple1 = (31,92,33,74,45)
>>> min(tuple1)
31
>>> list2 = ['w','t',3,5]
>>> list2.append('p')
>>> min(list2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()
报错提示意思就是不能拿字符串和整数进行比较。
4.7 sum(iterable[, start])
sum()方法用于返回序列iterable的总和,不过有一个默认参数start,意思就是从该值开始加起,默认值是0.
>>> list1 = [1,2,3,4,5,6]
>>> sum(list1)
21
>>> sum(list1, 2)
23
是从默认值在家上list1的总和。
4.8 sorted(iterable, key=None, reverse=False)
sorted()方法用于返回一个排序的列表,这里和列表的内置sort()方法有一点不同。sort() 是实现列表原地排序,而sorted()是返回一个新的列表:
>>> list1 = [6,3,9,8,2,5]
>>> list2 = list1[:]
>>> list1.sort()
>>> list1
[2, 3, 5, 6, 8, 9]
>>> sorted(list2)
[2, 3, 5, 6, 8, 9]
>>> list2
[6, 3, 9, 8, 2, 5]
4.9 reversed(sequence)
reversed()方法用于返回一个逆向迭代的值,实现效果和列表的内建方法一样reverse(),区别是列表的内建方法是原地翻转,而reverse()返回一个翻转后的迭代器对象。
>>> list1 = [2,7,4,3,9,1,-4,8]
>>> reversed(list1)
<list_reverseiterator object at 0x7f7fd1dfbe48>
>>> for i in reversed(list1):
... print(i, end=',')
...
8,-4,1,9,3,4,7,2,
4.10 enumerate(iterable)
enumerate()方法生成由二元组(二元组就是元素数量为2的元组)构称的一个迭代对象,每个二元组是由可迭代参数的索引号及其对应的元素组成的。看下面的例子:
>>> str1 = 'Python3v'
>>> for i in enumerate(str1):
... print(i)
...
(0, 'P')
(1, 'y')
(2, 't')
(3, 'h')
(4, 'o')
(5, 'n')
(6, '3')
(7, 'v')
4.11 zip(iter1 [,iter2[...]])
zip()方法用于返回由各个可迭代参数组成的元组,举个例子:
>>> list1 = [1,2,3,4,5,6,7,8]
>>> str1 = 'Python3v'
>>> for i in zip(list1,str1):
... print(i)
...
(1, 'P')
(2, 'y')
(3, 't')
(4, 'h')
(5, 'o')
(6, 'n')
(7, '3')
(8, 'v')
>>> tuple1 = ('q','w','e','r','t','y','u','i','o')
>>> for i in zip(list1,str1,tuple1):
... print(i)
...
(1, 'P', 'q')
(2, 'y', 'w')
(3, 't', 'e')
(4, 'h', 'r')
(5, 'o', 't')
(6, 'n', 'y')
(7, '3', 'u')
(8, 'v', 'i')
每一次分享都是自我提升的表现。。。。
评论列表