对多个变量设置相同的值时,用连等号一起赋值
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‘ : ‘lucy@g.com‘ }, { ‘name‘ : ‘lily‘ , ‘email‘ : ‘lily@g.com‘ }]
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的方式更直观