Python高效编码

2021-9-29 / 0评 / Python

对于使用Python来说,我们都知道,Pythonic这个意思,就是 The zen of Python(Python之禅),
如果你进入Python交互界面,然后输入: import this,会输出Tim Peters建议的Python编程规范。
houxiurong@hxr-mac ~$ python3                                                                   
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 05:52:31) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
>>>
不明白意思的话可以Google翻译一下,下面是使用Google翻译的结果,凑合先理解一波[\:狗头]
[Python 之禅,作者Tim Peters.
美丽总比丑陋好。
显式优于隐式。
简单胜于复杂。
复杂总比更复杂好。
扁平要比嵌套好。
稀疏要比密集好。
可读性非常重要。
特殊情况不足以打破规则。
虽然实用性胜过纯度。
错误永远不应该静默传递。
除非明确沉默。
面对模棱两可,拒绝猜测的诱惑。
应该有一种——最好只有一种——明显的方法来做到这一点。
尽管这种方式起初可能并不明显,除非您是荷兰人。
现在总比没有好。
尽管现在永远不会比*正确*更好。
如果实现很难解释,那是个坏主意。
如果实现很容易解释,这可能是一个好主意。
命名空间是一个很棒的想法——让我们做更多的事情!]


1.变量交换(swapping variables)
平常,我都是使用定义一个临时变量temp,(老师就是这么教的).
a=1
b=2

temp=a
a=b
b=temp
这样,变量就交换好了。
python中可以这样:
>>> a=1
>>> b=2
>>> a,b=b,a
>>> print(a)
2
>>> print(b)
1
简单吧!!!

2.字符串格式化(String formatting)
这个应该是使用的最大多的场景,比如字符串的组合拼接
>>> name="houxiurong.com"
>>> print("Hi,I'm "+name)
Hi,I'm houxiurong.com
如果仅仅是2个字符串的连接,这样没毛病,但是现实总是残酷的,需要考虑很多复杂的拼接。比如:
>>> name="houxiurong.com"
>>> country="china"
>>> age=28
>>> print("Hi,I'm "+name+". I'm from "+country+". And I'm "+str(age)+".")
Hi,I'm houxiurong.com. I'm from china. And I'm 28.
上述代码功能是能够实现,但是不够优雅易读,即我们写的代码99%是给人看的,如果写完代码永远不用修改,那么直接
写010101格式的不就好了,计算机更易于处理(扯远了)。而且在age输出时,是必须要进行类型转换,不然报错。
建议使用如下方式:
>>> print("Hi,I'm %s. I'm from %s. And I'm %d." % (name,country,age))
Hi,I'm houxiurong.com. I'm from china. And I'm 28.
上面占位符也不是很好看,还可以更好:
>>> print("Hi,I'm {}. I'm from {}. And I'm {}.".format(name,country,age))
Hi,I'm houxiurong.com. I'm from china. And I'm 28.
format()是字符串对象的一个格式化方法。
使用上述格式,如果需要指定位置,可以在{}中指定对应的参数位置,比如{0},{1}
>>> print("Hi,I'm {0}. I'm from {1}. And I'm {2} old.Yes,I am {0}".format(name,country,age))
>>> print("Hi,I'm {0}.Yes,I am {0},I am from {1},I am {2} old.".format(name,country,age))
Hi,I'm houxiurong.com.Yes,I am houxiurong.com,I am from china,I am 28 old.

上述对应的占位符数字就是format()里面对应的参数位置,从0开始数。
如果Python版本是3.6以上版本,则可以使用如下更加友好的方式: f-string表达式格式:
>>> print(f"Hi,I'm {name}.Yes,I am {name},I am from {country},I am {age} old.")
Hi,I'm houxiurong.com.Yes,I am houxiurong.com,I am from china,I am 28 old.
>>> print(f"Hi,I'm {name}.Yes,I am {name},I am from {country},I am {age+10} old.")
Hi,I'm houxiurong.com.Yes,I am houxiurong.com,I am from china,I am 38 old.

3.Yield语法(Yield Statement)
>>> def fib(n):
...    a=0
...    b=1
...    nums=[]
...    for _ in range(n):
...       nums.append(a)
...       a, b = b, a+b
...    return nums
... 
>>> fib(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

修改上面代码,使用yield,每当计算出一个元素时,就将该元素给送出去
def fib(n):
   a=0
   b=1
   for _ in range(n):
      yield a
      a, b = b, a+b
   return b

for i in fib(10):
    print(i)

好处是不需要等待整个列表都生成完毕后才输出结果,马上直接输出结果:
>>> def fibonacci(n):
...    a=0
...    b=1
...    for _ in range(n):
...       yield a
...       a,b=b,a+b
...    return b
... 
>>> print(fibonacci(10))
<generator object fibonacci at 0x7f9f613270a0>
>>> for i in fibonacci(10):
...    print(i)
... 
0
1
1
2
3
5
8
13
21
34
>>> 

4.列表解析式(List Comprehension)
>>> def toupper():
...    fruit=["apple","pear","pineapple","orange","banana"]
...    for i in range(len(fruit)):
...       fruit[i] = fruit[i].upper()
...       print(fruit[i])
... 
>>> toupper()
APPLE
PEAR
PINEAPPLE
ORANGE
BANANA
>>> 
上面代码可以被改写为更加简单的代码:
>>> def toupper():
...    fruit=["apple","pear","pineapple","orange","banana"]
...    fruit=[x.upper() for x in fruit]
...    return fruit
... 
>>> toupper()
['APPLE', 'PEAR', 'PINEAPPLE', 'ORANGE', 'BANANA']
>>> 

如果要过滤以a开头的水果,常用如下写法:
fruit = ["apple", "pear", "pineapple", "orange", "banana", "amemem"]
filtered_fruit = []
for f in fruit:
   if f.startswith("a"):
      filtered_fruit.append(f)
print(filtered_fruit)

简化后可以一行搞定,写法:
fruit = ["apple", "pear", "pineapple", "orange", "banana", "amemem"]
filtered_fruit = [f for f in fruit if f.startswith("a")]
print(filtered_fruit)

5.Enumerate(枚举)函数(Enumerate Function)
Python中关于循环的技巧:Enumerate()函数
fruit = ["apple", "pear", "pineapple", "orange", "banana"]
for i, x in enumerate(fruit):
    print(i, x)
>>>   
0 apple
1 pear
2 pineapple
3 orange
4 banana

6.反向遍历(Looping Backward)
fruit = ["apple", "pear", "pineapple", "zoo", "orange", "banana"]
for i, x in enumerate(reversed(fruit)):
    print(i, x)
>>> 
0 banana
1 orange
2 zoo
3 pineapple
4 pear
5 apple

7.按照字母顺序遍历(Looping in Sorted Order)
fruit = ["apple", "pear", "pineapple", "zoo", "orange", "banana"]
for i, x in enumerate(sorted(fruit)):
    print(i, x)
>>> 
0 apple
1 banana
2 orange
3 pear
4 pineapple
5 zoo

6.反向遍历(Looping Backward)
fruit = ["apple", "pear", "pineapple", "zoo", "orange", "banana"]
for i, x in enumerate(reversed(fruit)):
    print(i, x)
>>>
0 apple
1 banana
2 orange
3 pear
4 pineapple
5 zoo

7.字典的合并操作(Dictionary Merging)
a = {"ross": "123456", "xiaoming": "abc123"}
b = {"lilei": "111", "zhangsan": "12345678"}
c = {}
for k in a:
    c[k] = a[k]
for f in b:
    c[f] = b[f]
>>> print(c)
>>> {'ross': '123456', 'xiaoming': 'abc123', 'lilei': '111', 'zhangsan': '12345678'}

可以使用**解包格式处理,及c={**a,**b}
a = {"ross": "123456", "xiaoming": "abc123"}
b = {"lilei": "111", "zhangsan": "12345678"}
c={**a,**b}
>>> print(c)
>>> {'ross': '123456', 'xiaoming': 'abc123', 'lilei': '111', 'zhangsan': '12345678'}

8.三目运算符(Ternary Operator)
def ok(score):
    if score > 60:
        return "pass"
    else:
        return "fail"

比较高级的写法:
def ok2(score):
    result = "pass" if score > 60 else "fail"
    print(result)

9.序列解包(Sequence Unpacking)    
name = "hou xiruong"
# str_list = name.split()
# first_name = str_list[0]
# last_name = str_list[1]
# print(str_list)

first_name, last_name = name.split()
print(first_name)
print(last_name)
序列解包,序列可以是 list, tuple, range等

10.With语句(with statement)
对于文件的读写默认可以关闭,不用手动去close()调用,
类似java的 try(conn=connection.mysql(); ReaderInput=...) catch()
f = open("read.txt", "r")
s = f.read()
print(s)
f.close()

强烈建议使用:
with open("test.txt", "r") as f:
   s = f.read()
   print(s)
当with语句之后的代码执行完毕后,该打开的文件就会被Python自动关闭。

本文共计 20483 字,感谢您的耐心浏览与评论。

声明:土豆丝不辣|版权所有,违者必究|如未注明,均为原创|转载请注明原文链接说明出处

0条回应:“Python高效编码”