β

python有趣用法汇总

程序师 102 阅读

使用python过程中经常会不经意间遇到非常有趣的用法,于是特意搜集了一些

有趣的用法

1.for-else用法

循环正常结束则执行else语句。一般用于循环找符合条件的元素,如果找到则 break 调出循环,不会触发 else ;如果没有找到(完整运行循环)则 print not found

《Effictive Python》一书中对for-else用法提出了质疑,主要观点是可以通过封装成函数来取代这一用法,而封装成函数是更加通用易懂的做法,所以一般不会使用for-else用法。

2.try-else用法

如果没有触发异常就执行 else

参考 这里

3.解包用法

类似这样 a,b,c = ['a', 'b', 'c']

python有趣的解包用法

4.单行if-else

a = 1
b = 3 
if a == 1 
else 2
print('it is one' if a == 1 else 'no')

5.迭代器传入函数中不用加括号

# 一般是这样
a = (i for i in range(10))
sum(a)
# 我们可以这样
sum((i for i in range(10)))
# 但我们还可以这样
sum(i for i in range(10))
# 类似的有
' '.join(str(i) for i in range(10))

7.or的用法

python中 x or y 表示如果x为真就是x的值,否则为y的值

我们会经常看到类似这样的用法(比如函数的一个 value 参数没有设置默认值,这样使用就允许它不赋值)

value = value or {}
# 相当于
value = value if value else {}

8.and的用法

python中 x and y 表示如果x是假,结果就是x的值,否则就是y的值

x and y and z 多个and连接时,如果全是真结果就是最后一个的值;如果中间有假的值,结果就是第一个假的值

举一个例子

def not_empty(a):
    return a and a.strip()

not_empty(' a ')
# 值为 'a'
not_empty(None)
# 不会报错(如果 return a.strip() 就会报错)

# 在处理None的问题上相当于
def not_empty(a):
    if a is None:
        return None
    else:
        return a.strip()

细细品味and和or的差别,他们逻辑类似,但是实现的功能是不可以相互替代的

9.if value:

# 要用
if value:
# 不要用
if value == True:

这里总结一下这种情况下什么时候是 True ,什么时候是 False

False: 0 0.0 '' [] {} () set() None False

True:

另外要注意一点,我们用 if 判断一个对象是不是 None 的时候,要 if a is None 而不要直接 if a ,因为如果是后者,有非常多不是 None 的情况也会判定为 False ,比如空字符串、空列表等,为了精确指定 None 还是要用前者,这也是一种规范。

10.下划线的特殊使用

python中下划线是一种特殊的变量和符号,有一些特殊的用途

详见 python中下划线的使用

11.文档字符串

python有一种独一无二的注释方式,在包、模块、函数、类中第一句,使用 '''doc''' 这样三引号注释,就可以在对象中用 __doc__ 的方式提取

比较规范的写法是这样的(这里参考 grequests 模块的写法)

def myfun(a, b):
    '''add two numbers
    :param a: one number
    :param b: another number
    :returns: a number
    '''
    print(a + b)

print(myfun.__doc__)

# 结果为
add two numbers
    :param a: one number
    :param b: another number
    :returns: a number

其实参数还有其他的写法,如 numpy 库的写法,可以看 这里

除此之外,函数注释还有另一种方式,函数名可以直接调用某个参数的注释,详见 Python 的函数注释 。还可以参考 PEP 257

有用的函数

1.sum的本质

本质: sum(iterable, start=0) 将可迭代对象使用 + 连接

所以 sum([[1,2],[3,4]], []) 返回结果为 [1, 2, 3, 4]

2.range(start, stop[, step])

可以直接用 for i in range(10, 0, -1) 降序循环

3.enumerate循环索引

for index, item in enumerate(['a', 'b', 'c']):
    print(index, item)
输出:
 a
 b
 c

4.管道操作

func1(func2(func3(a)))写成类似a %>% func3 %>% func2 %>% func1,清晰展示函数执行的顺序,增强可读性

python本身不带有这样的用法,只是一些库提供了这样的用法,比如pandas和 syntax_sugar

参考 stackoverflow上的这个回答

其他

另外,就是一些基础的

阅读优秀的代码也是提高编程水平的好方法,参考下面这个问题

初学 Python,有哪些 Pythonic 的源码推荐阅读?

学习代码规范可以参考下面资料

更新补充

  1. for-else的更多讨论

下面引用《Effictive Python》一书中内容

a = 4 b = 9

for i in range(2, min(a, b) + 1):
print(‘Testing’, i)
if a % i == 0 and b % i == 0:
print(‘Not coprime’)
break
else:
print(‘Coprime’)

随后作者写到:

In practice, you wouldn’t write the code this way. Instead, you’d write a helper function to do the calculation. Such a helper function is written in two common styles.
The first approach is to return early when you find the condition you’re looking for. You return the default outcome if you fall through the loop.

def coprime(a, b):
for i in range(2, min(a, b) + 1):
if a % i == 0 and b % i == 0:
return False
return True

The second way is to have a result variable that indicates whether you’ve found what you’re looking for in the loop. You break out of the loop as soon as you find something.

def coprime2(a, b):
is_coprime = True
for i in range(2, min(a, b) + 1):
if a % i == 0 and b % i == 0:
is_coprime = False
break
return is_coprime

结尾:

Both of these approaches are so much clearer to readers of unfamiliar code. The expressivity you gain from the else block doesn’t outweigh the burden you put on people (including yourself) who want to understand your code in the future. Simple constructs like loops should be self-evident in Python. You should avoid using else blocks after loops entirely.

总结起来就是for-else的优势是可以被写函数的方式替代的

作者:程序师
用程序师的眼光看世界
原文地址:python有趣用法汇总, 感谢原作者分享。

发表评论