Pythonic风格

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangqiang1363/article/details/82814228
1、变量交换
>>> a = 1
>>> b = 2
>>> tmp = a
>>> a = b
>>> b = tmp
pythonic
>>> a, b = b, a

2、循环遍历区间元素
for i in [0, 1, 2, 3, 4, 5]:
    print i
# 或者
for i in range(6):
    print i
pythonic
for i in xrange(6):
    print i

3、带有索引位置的集合遍历
colors = ['red', 'green', 'blue', 'yellow']

for i in range(len(colors)):
    print i, '--->', colors[i]
pythonic
for i, color in enumerate(colors):
    print i, '--->', color

4、字符串连接
字符串连接时,普通的方式可以用 + 操作
names = ['raymond', 'rachel', 'matthew', 'roger',
         'betty', 'melissa', 'judith', 'charlie']

s = names[0]
for name in names[1:]:
    s += ', ' + name
print s
pythonic
print ', '.join(names)

5、打开/关闭文件
f = open('data.txt')
try:
    data = f.read()
finally:
    f.close()
pythonic
with open('data.txt') as f:
    data = f.read()

6、列表推导式
result = []
for i in range(10):
    s = i  2
    result.append(s)
pythonic
[i2 for i in xrange(10)]

7、善用装饰器
def web_lookup(url, saved={}):
    if url in saved:
        return saved[url]
    page = urllib.urlopen(url).read()
    saved[url] = page
    return page
pythonic
import urllib #py2
#import urllib.request as urllib # py3
def cache(func):
    saved = {}
    def wrapper(url):
        if url in saved:
            return saved[url]
        else:
            page = func(url)
            saved[url] = page
            return page
    return wrapper
@cache
def web_lookup(url):
    return urllib.urlopen(url).read()

8、合理使用列表
names = ['raymond', 'rachel', 'matthew', 'roger',
         'betty', 'melissa', 'judith', 'charlie']
names.pop(0)
names.insert(0, 'mark')
pythonic
from collections import deque
names = deque(['raymond', 'rachel', 'matthew', 'roger',
               'betty', 'melissa', 'judith', 'charlie'])
names.popleft()   # deque 是一个双向队列的数据结构,删除元素和插入元素会很快
names.appendleft('mark')

9、序列解包
p = 'vttalk', 'female', 30, '[email protected]'
name = p[0]
gender = p[1]
age = p[2]
email = p[3]
pythonic
name, gender, age, email = p

10、遍历字典的 key 和 value
# 方法一
for k in d:
    print k, '--->', d[k]
# 方法二
for k, v in d.items():
    print k, '--->', v
pythonic
for k, v in d.iteritems():
    print k, '--->', v

11、链式比较操作
age = 18
if age > 18 and x < 60:
    print("yong man")
pythonic
if 18 < age < 60:  
    print("yong man")
>>> False == False == True    # 这也是一个链式比较
False

12、if/else 三目运算
if gender == 'male':
    text = '男'
else:
    text = '女'
pythonic
text = '男' if gender == 'male' else '女'

13、真值判断
if attr == True:
    do_something()

if len(values) != 0: # 判断列表是否为空
    do_something()
pythonic
if attr:
    do_something()

if values:
    do_something()

14、for/else语句
flagfound = False
for i in mylist:
    if i == theflag:
        flagfound = True
        break
    process(i)
if not flagfound:
    raise ValueError("List argument missing terminal flag.")
pythonic
for i in mylist:
    if i == theflag:
        break
    process(i)
else:
    raise ValueError("List argument missing terminal flag.")

15、字符串格式化
s1 = "foofish.net"
s2 = "vttalk"
s3 = "welcome to %s and following %s" % (s1, s2)
pythonic
s3 = "welcome to {blog} and following {wechat}".format(blog="foofish.net", wechat="vttalk")

16、列表切片
items = range(10)
# 奇数
odd_items = []
for i in items:
    if i % 2 != 0:
        odd_items.append(i)
# 拷贝
copy_items = []
for i in items:
    copy_items.append(i)
pythonic
# 第1到第4个元素的范围区间
sub_items = items[1:4]
# 奇数
odd_items = items[1::2]
#拷贝
copy_items = items[::] 或者 items[:]

17、善用生成器
def fib(n):
    a, b = 0, 1
    result = []
     while b < n:
        result.append(b)
        a, b = b, a+b
    return result
pythonic
def fib(n):
    a, b = 0, 1
    while a < n:
        yield a
        a, b = b, a + b
上面是用生成器生成费波那契数列。生成器的好处就是无需一次性把所有元素加载到内存,只有迭代获取元素时才返回该元素,而列表是预先一次性把全部元素加载到了内存。此外用 yield 代码看起来更清晰。

18、获取字典元素
d = {'name': 'foo'}
if d.has_key('name'):
    print(d['name'])
else:
    print('unkonw')
pythonic
d.get("name", "unknow")

19、预设字典默认值
通过 key 分组的时候,不得不每次检查 key 是否已经存在于字典中。
data = [('foo', 10), ('bar', 20), ('foo', 39), ('bar', 49)]
groups = {}
for (key, value) in data:
    if key in groups:
        groups[key].append(value)
    else:
        groups[key] = [value]
pythonic
# 第一种方式
groups = {}
for (key, value) in data:
    groups.setdefault(key, []).append(value) 
# 第二种方式
from collections import defaultdict
groups = defaultdict(list)
for (key, value) in data:
    groups[key].append(value)

# dict.fromkeys('hello', 'world')

20、字典推导式
在python2.7之前,构建字典对象一般使用下面这种方式,可读性非常差
numbers = [1,2,3]
my_dict = dict([(number,number*2) for number in numbers])
print(my_dict)  # {1: 2, 2: 4, 3: 6}
pythonic
numbers = [1, 2, 3]
my_dict = {number: number * 2 for number in numbers}
print(my_dict)  # {1: 2, 2: 4, 3: 6}

# 还可以指定过滤条件
my_dict = {number: number * 2 for number in numbers if number > 1}
print(my_dict)  # {2: 4, 3: 6}

  1. #交换两个变量值    
  2. a,b = b,a    
  3.     
  4. #去掉list中的重复元素    
  5. old_list = [1,1,1,3,4]    
  6. new_list = list(set(old_list))    
  7.     
  8. #翻转一个字符串    
  9. s = 'abcde'    
  10. ss = s[::-1]    
  11.     
  12. #用两个元素之间有对应关系的list构造一个dict    
  13. names = ['jianpx', 'yue']    
  14. ages = [23, 40]    
  15. m = dict(zip(names,ages))    
  16.     
  17. #将数量较多的字符串相连,如何效率较高,为什么    
  18. fruits = ['apple', 'banana']    
  19. result = ''.join(fruits)    
  20.     
  21. #python字符串效率问题之一就是在连接字符串的时候使用‘+’号,例如 s = ‘s1’ + ‘s2’ + ‘s3’ + ...+’sN’,总共将N个字符串连接起来, 但是使用+号的话,python需要申请N-1次内存空间, 然后进行字符串拷贝。原因是字符串对象PyStringObject在python当中是不可变 对象,所以每当需要合并两个字符串的时候,就要重新申请一个新的内存空间 (大小为两个字符串长度之和)来给这个合并之后的新字符串,然后进行拷贝。 所以用+号效率非常低。建议在连接字符串的时候使用字符串本身的方法 join(list),这个方法能提高效率,原因是它只是申请了一次内存空间, 因为它可以遍历list中的元素计算出总共需要申请的内存空间的大小,一次申请完。    

21、多用lambda函数
# variable = lambda:  True

22、巧用 or 子句
# variable =  a  or  b

23、如何检测用户有没有传进来你想要的参数呢?
一个函数需要测试某个可选参数是否被使用者传递 进来。这时候需要小心的是你不能用某个默认值比如None、0 或者 False 值来测试用 户提供的值 因为这些值都是合法的值,是可能被用户传递进来的 。因此,你需要其 他的解决方案了。
为了解决这个问题,你可以创建一个独一无二的私有对象实例,就像上面 的 _no_value 变量那样。在函数里面,你可以通过检查被传递参数值跟这个实例是否一样来判断。这里的思路是用户不可能去传递这个 实例作为输入。因此,这
里通过检查这个值就能确定某个参数是否被传递进来了。

这里对object() 的使用看上去有点不太常见。object 是python 中所有类的基类。 你可以创建 object类的实例,但是这些实例没什么实际用处,因为它并没有任何有用 的方法,也没有哦任何实例数据 因为它没有任何的实例字典,你甚至都不能设置任何 属性值 。你唯一能做的就是测试同一性。这个刚好符合我的要求,因为我在函数中就 只是需要一个同一性的测试而已。
_no_value = object()
def  spam(a,  b=_no_value):
    if  b is  _no_value:
         print('No b value supplied')

24、偏函数的运用
# 减少可调用对象的参数个数

猜你喜欢

转载自blog.csdn.net/huangqiang1363/article/details/82814228