Python 基础学习
1、关于转义:
Python允许用r''表示''内部的字符串默认不转义。
>>> print('\\\t\\')
\ \
>>> print(r'\\\t\\')
\\\t\\
2、关于换行:
Python允许用'''...'''的格式表示多行内容。
>>> print('''line1
... line2
... line3''')
line1
line2
line3
3、关于空值:
空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。
4、关于极小(大)值:
注意:Python的整数没有大小限制,而某些语言的整数根据其存储长度是有大小限制的,例如Java对32位整数的范围限制在-2147483648-2147483647。Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf
5、关于list获取元素:
如果要取最后一个元素,除了计算索引位置外,还可以用-1做索引,直接获取最后一个元素:
>>>classmates[-1]
'Tracy'
以此类推,可以获取倒数第2个、倒数第3个:
>>>classmates[-2]
'Bob'
>>>classmates[-3]
'Michael'
6、关于一个元素的tuple:
只有1个元素的tuple定义时必须加一个逗号,,来消除歧义:
>>> t = (1,)
>>> t
(1,)
7、注意tuple不可变,但是仅指tuple指向的元素地址不可变:
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])
8、函数默认参数:
- 必选参数在前,默认参数在后.
- 定义默认参数要牢记一点:默认参数必须指向不变对象!
- 要注意定义可变参数和关键字参数的语法:args是可变参数,args接收的是一个tuple;kw是关键字参数,kw接收的是一个dict。使用args和**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
详情了解
9、Python的整数没有大小限制:
但是某些语言的整数根据其存储长度是有大小限制的,例如Java对32位整数的范围限制在-2147483648-2147483647
。
10、现在计算机系统通用的字符编码工作方式:
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。
11、关于tuple:
-
tuple一旦初始化就不能修改,不可变的tuple意义在于:因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
-
Python在显示只有1个元素的tuple时,也会加一个逗号,,以免你误解成数学计算意义上的括号,来消除歧义:
>>> t = (1,)
>>> t
(1,)
- tuple的“可变性”:
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])
12、eval()函数:
含义:eval() 函数用来执行一个字符串表达式,并返回表达式的值。
语法:eval(expression[, globals[, locals]])
# 示例1
>>> b = eval('{"a":1}')
>>> b
{'a': 1}
>>> print(type(b))
<class 'dict'>
# 示例2
>>> b = eval('3*3')
>>> b
9
13、如果有必要,可以先对参数的数据类型做检查;函数可以同时返回多个值,但其实就是一个tuple。
14、函数中定义默认参数要牢记一点:默认参数必须指向不变对象!
def add_end(L=[]):
L.append('END')
return L
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
原因解释如下:Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
15、Python中如果要对list实现类似Java那样的下标循环怎么办:
Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
for i, value in enumerate(['A', 'B', 'C']):
... print(i, value)
...
0 A
1 B
2 C
16、列表生成式,生成器,迭代器关系:
一类是集合数据类型,如list、tuple、dict、set、str等;一类是generator,包括生成器和带yield的generator function。这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
17、高阶函数:函数本身也可以赋值给变量,即:变量可以指向函数;
>>> f = abs
>>> f(-10)
10
既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def add(x, y, f):
return f(x) + f(y)
print(add(-5, 6, abs))
18、高阶函数的一种写法:
from functools import reduce
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def str2int(s):
def fn(x, y):
return x * 10 + y
def char2num(s):
return DIGITS[s]
return reduce(fn, map(char2num, s))
19、返回函数:
一个函数可以返回一个计算结果,也可以返回一个函数;返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。
20、偏函数:
当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。
from functools import partial
def mod( n, m ):
return n % m
mod_by_100 = partial( mod, 100 )
print mod( 100, 7 ) # 2
print mod_by_100( 7 ) # 2
21、reversed 函数:
返回一个反转的迭代器:
reversed(seq) # seq -- 要转换的序列,可以是 tuple, string, list 或 range。
# 字符串
seqString = 'Runoob'
print(list(reversed(seqString)))
22、Python的赋值、拷贝:
import copy
dict1 = {1: 1, 'user': 'test', 'num': [1, 2, 3]}
# 直接赋值
dict2 = dict1
dict3 = dict1.copy()
dict4 = copy.deepcopy(dict1)
dict1[1] = 11
dict1['user'] = '123'
dict1['num'].remove(1)
print('------------------------------------')
print('原字典修改后:', dict1)
print('直接赋值:', dict2)
print('浅拷贝:', dict3)
print('深拷贝:', dict4)
print('------------------------------------')
输出:
------------------------------------
原字典修改后: {1: 11, 'user': '123', 'num': [2, 3]}
直接赋值: {1: 11, 'user': '123', 'num': [2, 3]}
浅拷贝: {1: 1, 'user': 'test', 'num': [2, 3]}
深拷贝: {1: 1, 'user': 'test', 'num': [1, 2, 3]}
------------------------------------
-
对于字典、列表等非基本数据类型来说,直接赋值即给dict1对应的内存对象取了一个别名dict2,所以修改dict1即是修改dict2
-
浅拷贝只拷贝了父目录(根目录)的数据,非容器类型数据本身拷贝的就是数据本身,容器类型(列表,元组,集合,字典)的数据拷贝的是容器的别名,所以修改dict1的非容器类型数据时,并没有修改dict3的对应数据,而修改dict1的列表元素时,dict3对应的列表元素也修改了。
-
深拷贝递归拷贝所有目录的数据,完全在另外内存中复制了一份原字典,所以对dict1的修改不会影响dict4的数据。
23、and 和 or 的用法:
-
and:从左到右计算表达式,若所有的都为真,则返回最后一个值,若存在假,返回第一个假值.
-
or:从左到右计算表达式,只要遇到真值就返回那个真是,如果表达式结束依旧没有遇到真值,就返回最后一个假值.
print(1 or 3) # 1
print(1 and 3) # 3
print(0 and 2 and 1) # 0
print(0 and 2 or 1) # 1
print(0 and 2 or 1 or 4) # 1
print(0 or False and 1) # Flase
24、re 正则忽略大小写
re.search('test', 'TeSt', re.IGNORECASE)
re.match('test', 'TeSt', re.IGNORECASE)
re.findall(regex, word, re.IGNORECASE)
25、str.split VS re.split
-
str.split不支持正则及多个切割符号,不感知空格的数量,比如:
>>> s1="aa bb cc" >>> s1.split(" ") ['aa', 'bb', '', 'cc']
-
re.split,更强大,支持正则及多个字符切割;
>>> print line abc aa;bb,cc | dd(xx).xxx 12.12' xxxx # 按空格切 >>> re.split(r' ',line) ['abc', 'aa;bb,cc', '|', 'dd(xx).xxx', "12.12'\txxxx"] # 加将空格放可选框内[]内 >>> re.split(r'[ ]',line) ['abc', 'aa;bb,cc', '|', 'dd(xx).xxx', "12.12'\txxxx"] # 按所有空白字符来切割:\s([\t\n\r\f\v])\S(任意非空白字符[^\t\n\r\f\v] >>> re.split(r'[\s]',line) ['abc', 'aa;bb,cc', '|', 'dd(xx).xxx', "12.12'", 'xxxx'] # 多字符匹配 >>> re.split(r'[;,]',line) ['abc aa', 'bb', "cc | dd(xx).xxx 12.12'\txxxx"] >>> re.split(r'[;,\s]',line) ['abc', 'aa', 'bb', 'cc', '|', 'dd(xx).xxx', "12.12'", 'xxxx'] # 使用括号捕获分组的适合,默认保留分割符 re.split('([;])',line) ['abc aa', ';', "bb,cc | dd(xx).xxx 12.12'\txxxx"]
2.6、正则速查表
字符 | 描述 |
---|---|
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n ”匹配字符“n ”。“\n ”匹配一个换行符。串行“\\ ”匹配“\ ”而“\( ”则匹配“( ”。 |
^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n ”或“\r ”之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n ”或“\r ”之前的位置。 |
* |
匹配前面的子表达式零次或多次。例如,zo能匹配“z ”以及“zoo ”。等价于{0,}。 |
+ |
匹配前面的子表达式一次或多次。例如,“zo+ ”能匹配“zo ”以及“zoo ”,但不能匹配“z ”。+等价于{1,}。 |
? |
匹配前面的子表达式零次或一次。例如,“do(es)? ”可以匹配“does ”或“does ”中的“do ”。?等价于{0,1}。 |
{n} |
n是一个非负整数。匹配确定的n次。例如,“o{2} ”不能匹配“Bob ”中的“o ”,但是能匹配“food ”中的两个o。 |
{n,} |
n是一个非负整数。至少匹配n次。例如,“o{2,} ”不能匹配“Bob ”中的“o ”,但能匹配“foooood ”中的所有o。“o{1,} ”等价于“o+ ”。“o{0,} ”则等价于“o* ”。 |
{n,m} |
m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3} ”将匹配“fooooood ”中的前三个o。“o{0,1} ”等价于“o? ”。请注意在逗号和两个数之间不能有空格。 |
? |
当该字符紧跟在任何一个其他限制符(,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的*。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo ”,“o+? ”将匹配单个“o ”,而“o+ ”将匹配所有“o ”。 |
. |
匹配除“\ n ”之外的任何单个字符。要匹配包括“\ n ”在内的任何字符,请使用像(.|\n)的模式。 |
(pattern) |
匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用9属性。要匹配圆括号字符,请使用“\( ”或“\) ”。 |
(?:pattern) | 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。 |
(?=pattern) | 正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000 ”中的“Windows ”,但不能匹配“Windows3.1 ”中的“Windows ”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1 ”中的“Windows ”,但不能匹配“Windows2000 ”中的“Windows ”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 |
(?<=pattern) | 反向肯定预查,与正向肯定预查类拟,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows ”中的“Windows ”,但不能匹配“3.1Windows ”中的“Windows ”。 |
(?<!pattern) | 反向否定预查,与正向否定预查类拟,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows ”中的“Windows ”,但不能匹配“2000Windows ”中的“Windows ”。 |
x|y |
匹配x或y。例如,“z|food”能匹配“z ”或“food ”。“(z|f)ood”则匹配“zood ”或“food ”。 |
[xyz] |
字符集合。匹配所包含的任意一个字符。例如,“[abc] ”可以匹配“plain ”中的“a ”。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如,“[^abc] ”可以匹配“plain ”中的“p ”。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z] ”可以匹配“a ”到“z ”范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z] ”可以匹配任何不在“a ”到“z ”范围内的任意字符。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b ”可以匹配“never ”中的“er ”,但不能匹配“verb ”中的“er ”。 |
\B | 匹配非单词边界。“er\B ”能匹配“verb ”中的“er ”,但不能匹配“never ”中的“er ”。 |
\cx | 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c ”字符。 |
\d | 匹配一个数字字符。等价于[0-9]。 |
\D | 匹配一个非数字字符。等价于[^0-9]。 |
\f | 匹配一个换页符。等价于\x0c和\cL。 |
\n | 匹配一个换行符。等价于\x0a和\cJ。 |
\r | 匹配一个回车符。等价于\x0d和\cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于[^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于\x09和\cI。 |
\v | 匹配一个垂直制表符。等价于\x0b和\cK。 |
\w |
匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_] ”。 |
\W | 匹配任何非单词字符。等价于“[^A-Za-z0-9_] ”。 |
\xn | 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41 ”匹配“A ”。“\x041 ”则等价于“\x04&1 ”。正则表达式中可以使用ASCII编码。. |
*num* | 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1 ”匹配两个连续的相同字符。 |
*n* | 标识一个八进制转义值或一个向后引用。如果*n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n*为一个八进制转义值。 |
*nm* | 标识一个八进制转义值或一个向后引用。如果*nm之前至少有nm个获得子表达式,则nm为向后引用。如果*nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则*nm将匹配八进制转义值nm*。 |
*nml* | 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 |
\un | 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。 |