Python零散记录

记录Python中的各种方法、技巧、规范。

Posted by zhangshun on July 11, 2019

1.对文件操作时使用with语句,with语句在结束时会自动调用close()函数

1
2
with open('test.txt','r') as file:
	result = file.read()

2.zip()函数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表

1
2
3
4
5
6
7
8
9
10
11
12
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]

zipped = zip(a,b)			# 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]

zip(a,c)					# 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]

zip(*zipped)				# 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]

3.条件与循环的复用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#带有else语句的复用


expression1 if condition else expression2 for item in iterable

#等价于

for item in iterable:
	if condition:
		expression1
	else:
		expression2
 

#而如果没有 else 语句,则需要写成


expression1 for item in iterable if condition

#等价于

for item in iterable:
	if condition:
		expression1

#例如:将文件中逐行读取的一个完整语句,按逗号分割单词,去掉首位的空字符,并过滤掉长度小于等于 3 的单词,最后返回由单词组成的列表

text = ' Today,    is,Sunday'
text_list = [s.strip() for s in text.split(',') if len(s.strip()) > 3]
print(text_list)
['Today', 'Sunday']

#例如:给定下面两个列表 attributes 和 values,要求针对 values 中每一组子列表 value,输出其和 attributes 中的键对应后的字典,最后返回字典组成的列表,分别用一行和多行条件循环语句,来实现这个功能

attributes = ['name','dob','gender']
values = [['jason','2000-01-01','male'],
['mike','1999-01-01','male'],
['nancy','2001-12-01','female']
]

# expected outout:
[{'name': 'jason', 'dob': '2000-01-01', 'gender': 'male'},
{'name': 'mike', 'dob': '1999-01-01', 'gender': 'male'},
{'name': 'nancy', 'dob': '2001-12-01', 'gender': 'fmale'}]

#答案:[dict(zip(attributes,v)) for v in values]

4.join()方法,用于将序列中的元素以指定的字符连接生成一个新的字符串

1
2
3
4
5
6
7
8
9
10
list = ['my','name','is','zhangsan']

','.join(list)
'my,name,is,zhangsan'

' '.join(list)
'my name is zhangsan'

'-'.join(list)
'my-name-is-zhangsan'

5.字符串格式化用format()方法,string.format() 是最新的字符串格式函数与规范

6.用户自定义异常,实际工作中,如果内置的异常类型无法满足我们的需求,我们可以自定义所需异常类型

1
2
3
4
5
6
7
8
9
10
11
12
13
class MyInputError(Exception):
	"""Exception raised when there're errors in put."""
	def __init__(self,value):
		self.value = value
	def __str__(self):
		return ("{} is invalid input".format(repr(self.value)))

try:
	raise MyInputError(1)
except MyInputError as err:
	print('error: {}'.format(err))

#结果:error: 1 is invalid input

7.匿名函数,Python中有匿名函数的地方,都可以被替换成等价的其他表达式。一个Python程序是可以不用任何匿名函数的。不过使用匿名函数lambda,可以帮助我们大大简化代码的复杂度,提高代码的可读性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#匿名函数的格式:
lambda argument1, argument2,... argumentN : expression

#例如:
square = lambda x: x**2
square(3)
9


#lambda与常规函数的区别:
#第一、 lambda是一个表达式,并不是一个语句

[lambda x: x*x(x) for x in range(10)]

#lambda也可以被用作某些函数的参数,而常规函数def不能
l = [(1,20),(3,0),(9,10),(2,-1)]
l.sort(key=lambda x:x[1])	# 按列表中元组的第二个元素排序
print(l)
# 输出
[(2,-1),(3,0),(9,10),(1,20)]

#第二、 lambda的主体是只有一行的简单表达式,并不能扩展成一个多行的代码

#Python之所以发明lambda,就是为了让它和常规函数各司其职:lambda专注与简单的任务,而常规函数则负责更复杂的多行逻辑。

8.与匿名函数搭配使用的三个函数,map()、filter()、reduce()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#第一、 map(function,iterable),它表示,对iterable中的每一个元素,都运用function这个函数,最后返回一个新的可遍历的集合

#例如:读取文本中的ip,并添加到新的集合中
with open('test.txt','r') as File:
	data = File.readlines()
	new_list = map(lambda x:re.findall('(?:\d{1,3}\.){3}\d{1,3}',x) for x in data)

#第二、 filter(function,iterable),function同样表示一个函数对象。filter()函数表示对iterable中的每个元素,都是用function判断,最后将返回结果为True元素组成一个新的可遍历的集合

#例如:返回一个列表中的偶数
l = [2,3,4,5,6]
new_list = filter(lambda x:x % 2 == 0,l)

#第三、reduce(function,iterable),通常用来对一个集合做一些累积操作

#例如:计算某个集合元素的乘积
l = [1,2,3,4,5]
new_list = reduce(lambda x,y: x*y,l)

9.with打开多个文件

1
2
3
4
5
6
7
with open('file1') as f1:
    with open('file2) as f2:
        with open('file3') as f3:
            for i in f1:
                j = f2.readline()
                k = f3.readline()
                print(i,j,k)

这么多层缩进太恶心了,还是来一种简洁些的写法:

1
2
3
4
5
with open('file1') as f1, open('file2') as f2, open('file3') as f3:
    for i in f1:
        j = f2.readline()
        k = f3.readline()
        print(i,j,k)

10.str.isdigit(),检测字符串是否只由数字组成

1
2
3
4
5
6
7
8
str='123456'
print(str.isdigit())

str='this is string example ... wow!'
print(str.isdigit())

True
False

11.任何可迭代的对象可以通过一个简单的赋值语句解压并赋值给多个多个变量

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> data=['ACME',50,91.1,(2012,12,21)]
>>> name, shares, price ,date = data
>>> name
'ACME'
>>> date
(2012, 12, 21)

>>> data=['ACME',50,91.1,(2012,12,21)]
>>> _, shares, price ,_ = data
>>> shares
50
>>> price
91.1

解压可迭代对象赋值给多个变量

1
2
3
4
5
6
7
8
>>> record = ('Dave','dave@example.com','773-555-1212','847-555-1212')
>>> name, email, *phone_numbers = record
>>> name
'Dave'
>>> email
'dave@example.com'
>>> phone_numbers
['773-555-1212', '847-555-1212']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> records = [('foo',1,2),('bar','hello'),('foo',3,4)]
>>> def do_foo(x,y):
...     print('foo',x,y)
...
>>> def do_bar(s):
...     print('bar',s)
...
>>> for tag,*args in records:
...     if tag == 'foo':
...             do_foo(*args)
...     if tag == 'bar':
...             do_bar(*args)
...
foo 1 2
bar hello
foo 3 4