Be Pythonic

戚衡
2023-12-01

一直想写些东西,却一直没有付诸实践。今天也算是心血来潮吧,写些关于Pythonic的话题,文章的受众只能是一些Python新人。这里所说的新人包括两类: 第一类是完完全全的新人,第二类嘛,可能已经具备了一定的编程能力,只是刚刚接触Python而已。但无论如何,Python新人都希望自己的代码尽可能的Python化。

今天就来说说Pythonic的Python语法,与其它语言相比而言,也许会让你赏心悦目,眼前一亮哦.

交换赋值

a, b = b, a

一行代码完成了swap功能。

用unpack赋值

data = (18, 'male', 'Chian', 'beijing')
age, gender, country, city = data

让变量赋值变得更简单。

用if..else给变量赋值

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的代码呢

用if和iterator给数组(list)赋值

new_list = [n*n for n in range(1, 100) if n%5==0]

上面的代码实现了对(1, 100)列表进行遍历,找出其中5的倍数, 然后把这些数的平方重新赋值给new_list. 这看起来非常简单和清晰。

用filter和lambda删选列表数据

student = filter(lambda d: d["id"] == "100", dicts)

不用写循环就可以删选出数据哦。

交换字典的key和value

old_dict = {....}

new_dict = {v: k for k, v in old_dict.items()}

非常方便的实现了字典的key和value值的交换,省去了繁琐的遍历判断。

遍历列表时同时遍历value和index

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)了

用zip创建字典

keys = ['name', 'gender', 'age']
values = ['Jim', 'Male', 33]
my_dic = dict(zip(keys, values))
创建字典就是这么方便哦。

实现pythonic的switch结构

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对局部变量的搜索要大大快于全局变量

尽量使用 in

if x==5 or x==4 or x==3:
   pass

应该使用:

if x in (5, 4, 3):
   pass

尽量使用Python内建函数:

除非你是真正的大牛,不然的话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在特定的位置有一个变量,或者增加代码的可读性。

没有必要显式的比较一个值是否等于True或者None

if bool_value:
   pass
if none_value is None:
   pass

而不是:

if bool_value == True
   pass
if none_value == None 
   pass

使用isinstance进行类型比较

data=[1,2,3]
isinstance(data, list)
>>> True

而不是

type(data) == list
>>> True

不要问我为什么,太细节的代码我也没看过,但是isinstance 和type虽然同样在进行类型的比较,但是内部的步骤肯定是有区别的: isinstance直接去判断是否是给定的类型,而type传入的只是一个实例对象,肯定不会比isinstance高效,另外,type获取的类型还需要进行一次compare(==), 谁更高效不言而喻。

遍历的时候使用enumerate

list1 = ['a', 'b', 'c', 'd']
for index, value in enumerate(list1):
   print index, value
>>> 0 a
>>> 1 b
>>> 2 c
>>> 3 d

遍历的时候使用zip

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和while循环后的else块

  • 循环正常结束之后会调用else内的代码
  • 循环里通过break跳出循环,则不会执行else
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
 类似资料:

相关阅读

相关文章

相关问答