设为首页 收藏本站
查看: 778|回复: 0

[经验分享] 翻译《Writing Idiomatic Python》(三):变量、字符串、列表

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-11-29 09:05:28 | 显示全部楼层 |阅读模式
  原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/
  上一篇:翻译《Writing Idiomatic Python》(二):函数、异常
  下一篇:翻译《Writing Idiomatic Python》(四):字典、集合、元组

2.1 变量

2.1.1 对多个变量要赋同一个值时,使用链式赋值让语句变得简明
  Python支持链式赋值使多个变量可以在一次链式赋值中被设置为同一个值,这使得语句更加简明。
  不良风格:



1 x = 'foo'
2 y = 'foo'
3 z = 'foo'
  地道Python:



1 x = y = z = 'foo'
2.1.2 避免使用临时变量来实现值交换
  在Python中完全没有必要使用一个额外的临时变量来实现值交换。使用元组来实现不仅方便并且可读性更强。
  不良风格:



1 foo = 'Foo'
2 bar = 'Bar'
3 temp = foo
4 foo = bar
5 bar = temp
  地道Python:



1 foo = 'Foo'
2 bar = 'Bar'
3 (foo, bar) = (bar, foo)
2.2 字符串

2.2.1 对字符串相关的函数使用链式调用使意图更简明
  当对某个字符串数据进行一系列的处理时,直接在上一个调用后接下一个调用常常比起创建一系列临时变量的方法更加明确和简单。当然,如果链式调用太多也会破坏可读性,一般来说如果操作不超过三个使用链式调用会更好。
  不良风格:



1 book_info = ' The Three Musketeers: Alexandre Dumas'
2 formatted_book_info = book_info.strip()
3 formatted_book_info = formatted_book_infor.upper()
4 formatted_book_info = formatted_book_infor.replace(':', 'by')
  地道Python:



1 book_info = ' The Three Musketeers: Alexandre Dumas'
2 formatted_book_info = book_info.strip().upper().replace(':', 'by')
2.2.2 使用''.join连接列表中的字符串元素
  这样做更快,占用更低内存,并且这个用法在Python中非常普遍。注意下面的例子中使用的是用''连接字符串,实际在使用的时候可以替换为你想要的分隔符。
  不良风格:



1 result_list = ['True', 'False', 'File not found']
2 result_string = ''
3 for result in result_list:
4     result_string += result
  地道Python:



1 result_list = ['True', 'False', 'File not found']
2 result_string = ''.join(result_list)
2.2.3 使用ord获取字符的ASCII码,使用chr从ASCII码获取字符
  获取一个字符的ASCII码是一个有用的功能(比如字符串散列化),相应的,从ASCII得到对应的字符也常常很有用。
  Python中提供了两个内建的函数,chrord,可以实现字符和ASCII码之间的相互转化。
  不良风格:



1 hash_value = 0
2 character_hash = {
3     'a': 97,
4     'b': 98,
5     'c': 99,
6     # ...
7     'y': 121,
8     'z': 122,
9 }
10 for e in some_string:
11     hash_value += character_hash[e]
12 return hash_value
  地道Python:



1 hash_value = 0
2 for e in some_string:
3     hash_value += ord(e)
4 return hash_value
2.2.4 用format函数来进行字符串格式化
  一般来说又三种方式来进行字符串格式化:最简单但是最不推荐的就是用+来连接字符串。另一种方式是老式的利用%来格式化字符串的办法,在其他许多语言中也能看到这种方式,比如一些语言中的printf。这种方法比用+的方法好一些。
  在Python中,最地道和清晰的用法当属用format函数来进行字符串格式化。和老式的格式化方法类似,这种办法用带有格式的字符串作为模板并用一些值替换占位符生成最终字符串。比老式的格式化方法更好的地方是,在format函数中,我们可以命名占位符,获取占位符的对应变量的属性,控制字符宽度和填充等。format函数让字符串格式化显得简明。
  不良风格:



1 def get_formatted_user_info_worst(user):
2     # Tedious to type and prone to conversion errors
3     return 'Name: ' + user.name + ', Age: ' + str(user.age) + ', Sex: ' + user.sex
4
5 def get_formatted_user_info_slightly_better(user):
6     # No visible connection between the format string placeholders
7     # and values to use. Also, why do I have to know the type?
8     # Don't these types all have __str__ functions?
9     return 'Name: %s, Age: %i, Sex: %c' % (user.name, user.age, user.sex)
  地道Python:



1 def get_formatted_user_info(user):
2     # Clear and concise. At a glance I can tell exactly what
3     # the output should be. Note: this string could be returned
4     # directly, but the string itself is too long to fit on the
5     # page.
6     output = 'Name: {user.name}, Age: {user.age}, Sex: {user.sex}'.format(user=user)
7     return output
2.3 列表

2.3.1 使用列表解析从一个列表生成新的列表
  在恰当使用的情况下,列表解析会增加代码从一个列表中创建新列表的明确性。尤其是当新创建的列表是源列表的某种变换或者条件检查时。
  除了使代码更清晰,列表解析在执行效率上也非常高(CPython中)。
  不良风格:



1 some_other_list = range(10)
2 some_list = list()
3 for element in some_other_list:
4     if is_prime(element):
5         some_list.append(element + 5)
  地道Python:



1 some_other_list = range(10)
2 some_list = [element + 5 for element in some_other_list if is_prime(element)]
2.3.2 使用负数下标
  一个常被很多Python初用者忽视的特性是,在Python的列表和字符串中是可以使用负数下标的。和正数下标从列表开头向后数不同,附属下标从列表的末尾往回数。
  不良风格:



1 def get_suffix(word):
2     word_length = len(word)
3     return word[word_length - 2:]
  地道Python:



1 def get_suffix(word):
2     return word[-2:]
2.3.3 和内建的map()以及filter()函数相比,优先使用列表解析
  Python是一门自诞生以来就一直在演化的语言。也正因为如此,一直有一些历史遗留被保留了下来。mapfilter函数就是例子,尽管曾经在一些情况下用mapfilter是最佳的选择,但是现在几乎所有的使用都可以用列表解析来代替。并且列表解析的可读性和清晰性更好,所以至少在我的书里我认为应该优先使用列表解析而不是mapfilter的组合。
  不良风格:



1 the_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2 def is_odd(number):
3     return number % 2 == 1
4 odd_numbers = filter(is_odd, the_list)
5 odd_numbers_times_two = list(map(lambda x: x * 2, odd_numbers))
  地道Python:



1 the_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2 odd_numbers_times_two = [n * 2 for n in the_list if n % 2 == 1]
  // 其实这是个很见仁见智的问题,在stackoverflow上也有很多关于map/filter和list comprehension的争论,就效率而言,对不同的情况下两种办法互有胜负,就可读性而言其实我觉得map和filter比list comprehension好很多。。另外别忘了还有个函数叫reduce

2.3.4 使用内建的sum函数对列表中的元素求和
  对于一些已经用习惯sum的人来说可能会觉得这条比较奇怪。然而对更多的Python新手而言他们做的是自己重新实现了sum函数。如果一个函数已经是内建的,那么我们不应该重新发明轮子。
  不良风格:



1 the_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2 the_sum = 0
3 for element in the_list:
4     the_sum += element
  地道Python:



1 the_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2 the_sum = sum(the_list)
2.3.5 使用all检查一个可遍历结构中是否所有元素都是真
  和sum一样,all也是一个被新手频繁重写的内建函数。它可以检查一个可遍历结构中的元素是否都为真。
  不良风格:



1 def contains_zero(iterable):
2     for e in iterable:
3         if e == 0:
4             return True
5     return False
  地道Python:



1 def contains_zero(iterable):
2     # 0 is "Falsy," so this works
3     return not all(iterable)
2.3.6 优先使用xrange而不是range,除非你需要的就是range生成的列表
  xrangerange都能让你遍历一个数值列表。区别是,xrange不会再内存中存储一个完整的列表。大多数情况下这两者不会再实际使用时产生区别,但是当你需要遍历的数值范围非常大时,在内存占用和执行效率上就能看到很大差别了。
  不良风格:



1 # A loop over a large range that breaks out
2 # early: a double whammy!
3 even_number = int()
4 for index in range (1000000):
5     if index % 2 == 0:
6         even_number = index
7         break
  地道Python:



1 even_number = int()
2 for index in xrange(1000000):
3     if index % 2 == 0:
4         even_number = index
5         break
  转载请注明出处:達聞西@博客园
  上一篇:翻译《Writing Idiomatic Python》(二):函数、异常
  下一篇:翻译《Writing Idiomatic Python》(四):字典、集合、元组

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-144786-1-1.html 上篇帖子: python scrapy+Mongodb爬取蜻蜓FM,酷我及懒人听书 下篇帖子: Python字符串基础一
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表