python编程技巧

可变类型和不可变类型

Python提供两种内置或用户定义的类型。可变类型允许内容的内部修改。典型的动态类型 包括列表与字典:列表都有可变方法,如 list.append()list.pop(), 并且能就地修改。字典也是一样。不可变类型没有修改自身内容的方法。比如,赋值为整数 6的变量 x 并没有 “自增” 方法,如果需要计算 x + 1,必须创建另一个整数变量并给其命名。

这种差异导致的一个后果就是,可变类型是不 ‘稳定 ‘的,因而不能作为字典的键使用。合理地 使用可变类型与不可变类型有助于阐明代码的意图。例如与列表相似的不可变类型是元组, 创建方式为 (1, 2)。元组是不可修改的,并能作为字典的键使用。

Python 中一个可能会让初学者惊讶的特性是:字符串是不可变类型。这意味着当需要组合一个 字符串时,将每一部分放到一个可变列表里,使用字符串时再组合 (‘join’) 起来的做法更高效。 值得注意的是,使用列表推导的构造方式比在循环中调用 append() 来构造列表更好也更快。

1
2
3
4
5
# 创建将019连接起来的字符串 (例 "012..1819")
nums = ""
for n in range(20):
nums += str(n) # 慢且低效
print nums

1
2
3
4
5
# 创建将019连接起来的字符串 (例 "012..1819")
nums = []
for n in range(20):
nums.append(str(n))
print "".join(nums) # 更高效

避免对不同类型的对象使用同一个变量名

1
2
3
4
a = 1
a = 'a string'
def a():
pass # 实现代码

1
2
3
4
count = 1
msg = 'a string'
def func():
pass # 实现代码

更好

1
2
3
# 创建将019连接起来的字符串 (例 "012..1819")
nums = [str(n) for n in range(20)]
print "".join(nums)

极佳

1
2
3
# 创建将019连接起来的字符串 (例 "012..1819")
nums = map(str, range(20))
print "".join(nums)

最后关于字符串的说明的一点是,使用 join() 并不总是最好的选择。比如当用预先 确定数量的字符串创建一个新的字符串时,使用加法操作符确实更快,但在上文提到的情况 下或添加到已存在字符串的情况下,使用 join() 是更好

1
2
3
4
5
6
foo = 'foo'
bar = 'bar'

foobar = foo + bar # 好的做法
foo += 'ooo' # 不好的做法, 应该这么做:
foo = ''.join([foo, 'ooo'])

除了 str.join()+,您也可以使用 % 格式运算符来连接确定数量的字符串,但 PEP 3101 建议使用 str.format() 替代 % 操作符。

1
2
3
4
5
6
foo = 'foo'
bar = 'bar'

foobar = '%s%s' % (foo, bar) # 可行
foobar = '{0}{1}'.format(foo, bar) # 更好
foobar = '{foo}{bar}'.format(foo=foo, bar=bar) # 最好

使用简短的函数或方法能降低对不相关对象使用同一个名称的风险。即使是相关的不同 类型的对象,也更建议

使用不同命名:

1
2
3
items = 'a b c d'  # 首先指向字符串...
items = items.split(' ') # ...变为列表
items = set(items) # ...再变为集合

重复使用命名对效率并没有提升:赋值时无论如何都要创建新的对象。然而随着复杂度的 提升,赋值语句被其他代码包括 ‘if’ 分支和循环分开,使得更难查明指定变量的类型。 在某些代码的做法中,例如函数编程,推荐的是从不重复对同一个变量命名赋值。Java 内的实现方式是使用 ‘final’ 关键字。Python并没有 ‘final’ 关键字而且这与它的哲学 相悖。尽管如此,避免给同一个变量命名重复赋值仍是是个好的做法,并且有助于掌握 可变与不可变类型的概念。

单行描述单行代码

每一行一个语句,尤其在复杂的逻辑表达式的时候,这样会清晰很容易阅读。

1
2
print "one";print "two"
if x == 1;print "one"

1
2
3
4
print "one"
print "two"
if x == 1:
print "one"

技巧

使用enumerate() 将列表中的每个项提供两个元素的元组,一个是下标,一个是值。

1
2
for index , iteme in enumerate(sorted_list):
print(index,iteme)

交换变量

1
a,b=b,a

访问字典元素

不要使用该dict.has_key()方法。相反使用语法或传递默认参数 比如x in dict ,dict.get(k,default_value)

1
2
3
4
5
d = {“hello”: "world"}
if d.has_key("hello"):
print(d['hello'])
else:
print("fault values")

1
2
3
4
5
6
d = {“hello”: "world"}
print(d.get("hello"),"fault vluse")

# or
if "hello" in d:
print(d[“hello”])