分享书籍[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的方式更直观

分享书籍[writing idiomatic python ebook] 二,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。