这是我在python中编写的第一件事.我来自Java背景.我不想只学习如何用Python语法编写java代码.我想学习如何用pythonic范例编程.
你能不能评论我如何使下面的代码更pythonic?
from math import sqrt # recursively computes the factors of a number def factors(num): factorList = [] numroot = int(sqrt(num)) + 1 numleft = num # brute force divide the number until you find a factor for i in range(2, numroot): if num % i == 0: # if we found a factor, add it to the list and compute the remainder factorList.append(i) numleft = num / i break # if we didn't find a factor, get out of here! if numleft == num: factorList.append(num) return factorList # now recursively find the rest of the factors restFactors = factors(numleft) factorList.extend(restFactors) return factorList # grabs all of the twos in the list and puts them into 2 ^ x form def transformFactorList(factorList): num2s = 0 # remove all twos, counting them as we go while 2 in factorList: factorList.remove(2) num2s += 1 # simply return the list with the 2's back in the right spot if num2s == 0: return factorList if num2s == 1: factorList.insert(0, 2) return factorList factorList.insert(0, '2 ^ ' + str(num2s)) return factorList print transformFactorList(factors(#some number))
unmounted.. 22
大卫·古德(David Goodger)在这里有一本名为"像Python一样的代码"的优秀入门书.重新命名(引用)该文本的几件事:
joined_lower
用于功能,方法,属性
joined_lower
或常量的ALL_CAPS
StudlyCaps
对于课程
camelCase
只是为了符合已有的惯例
Thomas Woute.. 21
只需使用'import math'和'math.sqrt()'代替'from math import sqrt'和'sqrt()'; 你只是导入'sqrt'就不会赢得任何东西,并且代码很快会因为太多的导入而变得笨拙.此外,当你大量使用from-import时,reload()和mock for out等测试会更快地破解.
divmod()函数是执行除法和模数的便捷方式.您可以使用/ else而不是对numleft进行单独检查.您的因子功能是发电机的自然候选者.另一个答案中已经提到了xrange().这就是这样做的全部:
import math # recursively computes the factors of a number as a generator def factors(num): numroot = int(math.sqrt(num)) + 1 # brute force divide the number until you find a factor for i in xrange(2, numroot): divider, remainder = divmod(num, i) if not remainder: # if we found a factor, add it to the list and compute the # remainder yield i break else: # if we didn't find a factor, get out of here! yield num return # now recursively find the rest of the factors for factor in factors(divider): yield factor
使用生成器意味着您只能迭代结果一次; 如果您只想要一个列表(就像在translateFactorsList中那样),则必须将调用包装在lists()中的factors()中.
大卫·古德(David Goodger)在这里有一本名为"像Python一样的代码"的优秀入门书.重新命名(引用)该文本的几件事:
joined_lower
用于功能,方法,属性
joined_lower
或常量的ALL_CAPS
StudlyCaps
对于课程
camelCase
只是为了符合已有的惯例
只需使用'import math'和'math.sqrt()'代替'from math import sqrt'和'sqrt()'; 你只是导入'sqrt'就不会赢得任何东西,并且代码很快会因为太多的导入而变得笨拙.此外,当你大量使用from-import时,reload()和mock for out等测试会更快地破解.
divmod()函数是执行除法和模数的便捷方式.您可以使用/ else而不是对numleft进行单独检查.您的因子功能是发电机的自然候选者.另一个答案中已经提到了xrange().这就是这样做的全部:
import math # recursively computes the factors of a number as a generator def factors(num): numroot = int(math.sqrt(num)) + 1 # brute force divide the number until you find a factor for i in xrange(2, numroot): divider, remainder = divmod(num, i) if not remainder: # if we found a factor, add it to the list and compute the # remainder yield i break else: # if we didn't find a factor, get out of here! yield num return # now recursively find the rest of the factors for factor in factors(divider): yield factor
使用生成器意味着您只能迭代结果一次; 如果您只想要一个列表(就像在translateFactorsList中那样),则必须将调用包装在lists()中的factors()中.
您可能想要看的另一件事是文档字符串.例如,此函数的注释:
# recursively computes the factors of a number def factors(num):
可以转换成这个:
def factors(num): """ recursively computes the factors of a number"""
这样做并不是真的100%必要,但如果你开始使用pydoc的东西,这是一个很好的习惯.
你也可以这样做:
"""This is a docstring"""
>>> import docstring >>> help(docstring)
Help on module docstring: NAME docstring - This is a docstring FILE /Users/jason/docstring.py
一些评论:
我会替换range()
为xrange()
; 当你调用时range()
,它会同时分配整个范围,而当你迭代时xrange()
,它会一次返回一个结果,从而节省内存.
不要将条件后的表达式放在同一行(if num2s -- 0: return factorList
)上.它使得一眼就能看到它正在做什么变得更加困难(这是一个障碍).
不要害怕使用模块.该[sympy][1]
模块已经具有计算因子的代码,这可以通过消除大部分代码来简化代码.
Python的字符串格式化简单而有效.
例如:
factorList.insert(0, '2 ^ ' + str(num2s))
可以改为
factorlist.insert(0, '2 ^ %s' % num2s)
总而言之,我发现你的代码并不是广泛的非pythonic.只要确保你想要使用地板划分,因为这是默认情况下会发生的整数值.否则,您需要修复除法运算符:
from __future__ import division
有时令人沮丧的语言警告.