分享书籍[writing idiomatic python ebook] 二
对多个变量设置相同的值时,用连等号一起赋值
1
2
3 |
x =
10 y =
10 z =
10 |
改成:
1 |
x =
y = z = 10 |
交换变量值时,可以避免定义新的临时变量
1
2
3
4
5
6 |
x =
10 y =
5 temp =
x x =
y y =
temp |
改成:
1
2
3
4 |
x =
10 y =
5 x, y =
y, x |
多次调用字符对象方法时,可以用链式调用方法,避免中间产生过多变量
1
2
3
4 |
str1 =
‘i am a bug!‘ str2 =
str1.strip() str3 =
str2.upper() str4 =
str3.replace( ‘!‘ , ‘?‘ ) |
改成:
1 |
str4 =
str1.strip().upper().replace( ‘!‘ , ‘?‘ ) |
当然,如果连续调用链过长,也会使代码不清楚,作者给的建议是最好不要超过三次调用
拼接字符列表时,用join方法去实现
1
2
3
4 |
mylist =
[ ‘i‘ , ‘am‘ , ‘a‘ , ‘bug‘ ] resultStr =
‘‘ for e in
mylist: resultStr + =
e |
改成:
1
2 |
mylist =
[ ‘i‘ , ‘am‘ , ‘a‘ , ‘bug‘ ] resultStr =
‘‘.join(mylist) |
格式化字符时多使用format函数
我们格式化字符时一般会用下面两种方式:
1
2
3
4
5 |
name =
"tony" age =
100 str
= "myname : " +
name +
" my age : " +
str (age) str1 =
"myname : %s my age : %d" %
(name, age) |
改成:
1 |
str2 =
"myname : {} my age {}" . format (name, age) |
对list对象进行相关操作并生成新的对象时多使用comprehension(这个怎么翻译?)
1
2
3
4
5
6 |
mylist =
range ( 20 ) odd_list =
[] for e in
mylist: if
e % 2 = =
1 : odd_list.append(e) |
改成:
1
2 |
mylist =
range ( 20 ) odd_list =
[e for
e in
mylist if
e % 2 = =
1 ] |
这种写法性能更好
有时候使用负列表索引更方便
1
2
3
4 |
mylist =
range ( 20 ) len_mylist =
len (mylist) last_five_list =
mylist[len_mylist -
5 :] |
改成:
1 |
last_five_list =
mylist[ - 5 :] |
判断一个列表里的元素是否都为True时,可以对列表进行all操作
1
2
3
4
5 |
def contains_zero(itor): for
e in
itor: if
e: return
False return
True |
改成:
1
2 |
def contains_zero(itor): return
all (itor) |
all只有在列表中的每个元素都返回True时才会返回True
区别xrange和range
range会在内存中生成完整的列表实例, 而xrange则只是生成一个迭代器;
如下我只想打印一个集合中第一个偶数
1
2
3
4
5 |
for index in
range ( 3 , 1000000000 ): if
index %
2 = =
0 : print
index break |
在我机器上会出现如下错误,就是因为range会在内存中生成完整对象实例:
1
2
3
4
5 |
Traceback (most recent call last): File
"C:\Users\tony\Desktop\huawei.py" , line 3 , in
<module> for
index in
range ( 3 , 1000000000 ): MemoryError [Finished in
0.2s with exit code 1 ] |
改成如下就正常了:
1
2
3
4 |
for index in
xrange ( 3 , 1000000000 ): if
index %
2 = =
0 : print
index break |
用dict对象完成switch...case...的功能
在python里没有switch...case...功能。但是dict可以编写出更直观简洁的代码出来。如下,模拟一个计算器的功能,根据传入的操作符和操作数来算出结果:
1
2
3
4
5
6
7
8
9 |
def apply_operation(left_operand, right_operand, operator): if
operator = =
‘+‘ : return
left_operand +
right_operand elif
operator = =
‘-‘ : return
left_operand -
right_operand elif
operator = =
‘*‘ : return
left_operand *
right_operand elif
operator = =
‘/‘ : return
left_operand /
right_operand |
改成:
1
2
3
4 |
def apply_operation(left_operand, right_operand, operator): import
operator as op operator_mapper =
{ ‘+‘ : op.add, ‘-‘ : op.sub, ‘*‘ : op.mul, ‘/‘ : op.truediv} return
operator_mapper[operator](left_operand, right_operand) |
使用dict.get方法可以提供一个默认值
我们在获取dict的某个元素时,因为不确定该键是否存在,所以一般是先检查,再获取。如下:
1
2
3
4
5
6
7 |
mydict =
{ ‘a‘ : 1 } default_b =
2 if ‘b‘ in mydict: default_b =
mydict[ ‘b‘ ] print
default_b |
改成:
1 |
print
mydict.get( ‘b‘ , 2 ) |
大家或许只知道list的comprehension,其实dict也有comprehension
1
2
3
4
5
6
7 |
user_list =
[{ ‘name‘ : ‘lucy‘ , ‘email‘ : ‘[email protected]‘ }, { ‘name‘ : ‘lily‘ , ‘email‘ : ‘[email protected]‘ }] user_email =
{} for user in
user_list: if
‘email‘ in user: user_email[user[ ‘name‘ ]] =
user[ ‘email‘ ] |
改成:
1 |
{user[ ‘name‘ ]: user[ ‘email‘ ] for
user in
user_list if
‘email‘ in user} |
利用set的集合运算功能
在很多场景中,我们经常要从两个集合(列表)中找出相同的,相异的,或者相互排除的元素列表,这个时候我们可以利用set本身支持的各种集合运算功能。就像数学中讲的集合的:相交,相并,异合等等。
如下我们要计算出满足两个特殊的相交集:
1
2
3
4
5
6
7 |
def get_both_popular_and_active_users(): most_popular_users =
get_list_of_most_popular_users() most_active_users =
get_list_of_most_active_users() popular_and_active_users =
[] for
user in
most_active_users: if
user in
most_popular_users: popular_and_active_users.append(user) |
改成:
1
2 |
def get_both_popular_and_active_users(): return ( set (get_list_of_most_active_users()) & set (get_list_of_most_popular_users())) |
set支持的运算有: A & B, A | B, A ^ B 。还有一点要注意的,set在计算的时候如何判定两个元素相等的呢,除了要在类中定义的__eq__方法返回值相同外,还要定义 __hash__ 值相同。这点和java中的HashMap的判定行为(equals, hashCode)差不多
set的comprehension
到这里我们可以比较下list, dict, set 三种数据结构的comprehension的不同表述。list用[...], dict用{key:value...}, 而set用{...}
1
2
3 |
users_first_names =
set () for user in
users: users_first_names.add(user.first_name) |
改成:
1 |
users_first_names =
{user.first_name for
user in
users} |
访问tuple的数据项时,可以用namedtuple代替index的方式访问
1
2
3
4 |
rows =
[( ‘lily‘ , 20 , 2000 ), ( ‘lucy‘ , 19 , 2500 )] for row in
rows: print
‘{}`age is {}, salary is {} ‘ . format (row[ 0 ], row[ 1 ], row[ 2 ]) |
改成:
1
2
3
4
5 |
Employee =
namedtuple( ‘Employee‘ , ‘name, age, salary‘ ) for row in
rows: employee =
Employee._make(row) print
‘{}`age is {}, salary is {} ‘ . format (employee.name, employee.age, employee.salary) |
namedtuple方法会成一个tuple的子类,并通过类方法_make可以把一个tuple实例转换成一个可以通过name来索引的对象。这比通过index的方式更直观
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。