一直想写些东西,却一直没有付诸实践。今天也算是心血来潮吧,写些关于Pythonic的话题,文章的受众只能是一些Python新人。这里所说的新人包括两类: 第一类是完完全全的新人,第二类嘛,可能已经具备了一定的编程能力,只是刚刚接触Python而已。但无论如何,Python新人都希望自己的代码尽可能的Python化。
今天就来说说Pythonic的Python语法,与其它语言相比而言,也许会让你赏心悦目,眼前一亮哦.
a, b = b, a
一行代码完成了swap功能。
data = (18, 'male', 'Chian', 'beijing')
age, gender, country, city = data
让变量赋值变得更简单。
is_adult = True if age >= 18 else False
上面的这行代码用来判断是否是 成年人,如果大于等于18岁,就is_adult就赋值True,反之False。而传统的if..else结构可能会是这样的:
if age >= 18{
is_adult = True
}
else:{
is_adult = False
}
对比之下,你是否更喜欢Pythonic的代码呢
new_list = [n*n for n in range(1, 100) if n%5==0]
上面的代码实现了对(1, 100)列表进行遍历,找出其中5的倍数, 然后把这些数的平方重新赋值给new_list. 这看起来非常简单和清晰。
student = filter(lambda d: d["id"] == "100", dicts)
不用写循环就可以删选出数据哦。
old_dict = {....}
new_dict = {v: k for k, v in old_dict.items()}
非常方便的实现了字典的key和value值的交换,省去了繁琐的遍历判断。
for index, value in enumerate(my_list):
print (index, value)
遍历数组时,可以同时获取到value和index, 无需再根据index取value。
with open(path_to_file, 'w') as file_handle:
file_handle.write("Hello world")
文件对象会自动关闭,无需显式关闭。
my_list = [0]*10
print my_list
>>> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
names = ['Tom', 'Jack', 'Sam']
','.join(names)
很简洁,虽然未必是python所独有。
str = "Hello" print "Jim, %s" % str 或者 name = "Jim" greet = "Hello" print "{name}, {msg}".format(name=name, msg=greet) 值得注意的是: 带关键字的字符串格式化是可以任意调换变量顺序的。
if 0 < n <=100:
pass
可以放弃传统的(n>0 && n<=100)了
keys = ['name', 'gender', 'age']
values = ['Jim', 'Male', 33]
my_dic = dict(zip(keys, values))
创建字典就是这么方便哦。
def f(n):
return {
0: "Green",
1: "Red",
2: "Black",
}.get(n, "Default value")
Python没有switch关键字,聊胜于无。但python字典的get方法还是要点个赞的,不但可以规避字段的key不存在的error,此外当不存在时,也可以返回"Default value"
students = [['Tom', (98, 96)], ['Jack', (98, 100)]]
for name, (score_m, score_p) in students:
print(name, score_m, score_p)
很多情况下,我们遍历二维数组不再需要嵌套遍历了哦
让自己的python代码更加高效和符合规范一定不是一件坏事。我们也许无法每个人都变身为算法达人,事实上也没必要 ,但了解一些python自己的准则确实会让你的代码得到改进。
避免 "global" 关键字, 使用局部变量。因为Python对局部变量的搜索要大大快于全局变量
if x==5 or x==4 or x==3:
pass
应该使用:
if x in (5, 4, 3):
pass
除非你是真正的大牛,不然的话Python内建的函数应该比你的高效。当然这也要区别对待,有的时候内建函数可能返回过多的数据,而你其实只需要其中很少的一部分,而你确信你自己的方法对于获取这样的数据肯定会比内建函数高效。
a, b = b, a
而不是传统的swap方式
chars = ['s', 'p', 'a', 'm']
word = ''.join(chars)
比方说你需要进行解包赋值(unpacking), 但是你并不需要所有的值,那么:
data = [1, 2, 3]
a, __, b = data
print a, b
__就代表一个可以忽略的变量,它的创建只是为了告诉Python在特定的位置有一个变量,或者增加代码的可读性。
if bool_value:
pass
if none_value is None:
pass
而不是:
if bool_value == True
pass
if none_value == None
pass
data=[1,2,3]
isinstance(data, list)
>>> True
而不是
type(data) == list
>>> True
不要问我为什么,太细节的代码我也没看过,但是isinstance 和type虽然同样在进行类型的比较,但是内部的步骤肯定是有区别的: isinstance直接去判断是否是给定的类型,而type传入的只是一个实例对象,肯定不会比isinstance高效,另外,type获取的类型还需要进行一次compare(==), 谁更高效不言而喻。
list1 = ['a', 'b', 'c', 'd']
for index, value in enumerate(list1):
print index, value
>>> 0 a >>> 1 b >>> 2 c >>> 3 d
students = ["Jim", "Cici"]
schools = ["abc", "xyz"]
for sdt, sch in zip(students, schools):
print sch + ":“ + sdt
>>> abc: Jim >>> xyz: Cici
并且也支持遍历时直接返回一个元组
list1 = [1, 2]
list2 = ['a', 'b', 'c', 'd']
for t in zip(list1,list2):
print t
>>> (1, 'a') >>> (2, 'b')
for i in range(2):
print(i)
if i % 2 == 0:
break
else:
print('loop finish')
>>> 0
对于普通的序列(列表),我们可以通过内置的reversed()函数进行反向迭代:
for i in reversed(my_list):
print(i)
语法: list[start:end:step]
x = [1,2,3,4,5,6] print x[:3] #前3个 >>> [1,2,3] print x[1:4] #中间3个, 从index1开始,index3结束 >>> [2,3,4] print x[-3:] #倒数3个 >>> [4,5,6] print x[::2] >>> [1,3,5] #奇数项,从index0开始,end默认为数组的长度, step=2, print x[1::2] #偶数项, 从index1开始,end默认为数组的长度, step=2, >>> [2,4,6]
s="12345"
print s[::-1]
>>> 54321
其实这个反向的方法同样适应于列表
def sum(*args):
result = 0
for num in args:
result += num
return result
sum(1, 2)
>>> 3
sum(1, 2, 3, 4)
>>> 10
也可以直接传入列表,用*进行解构
sum(*[1, 2, 3, 4])
>>> 10