美文网首页爬虫进化日记
Python高阶(三) - 我的Pythonic日记

Python高阶(三) - 我的Pythonic日记

作者: Spareribs | 来源:发表于2017-07-12 20:59 被阅读57次

    1. 循环遍历可迭代对象(in enumerate)

    Non-Pythonic

    # 基于索引的while循环
    choices = ['red', 'green', 'blue']
    i = 0
    while i < len(choices):
        print('{}) {}'.format(i, choices[i]))
        i += 1
        
    # 或者for循环:
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
    

    Pythonic

    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
    
    # 加上序列的枚举
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))
    

    2 (字典 集合 列表)推导式

    Non-Pythonic

    # 字典推导式
    
    # 列表推导式
    result = []
    for i in range(10):
        s = i  2
        result.append(s)
    

    Pythonic

    # 列表推导式
    [i2 for i in xrange(10)]
    

    3 漂亮的打印出JSON

    >>> import json
    >>> print(json.dumps(data))  # No indention
    {"status": "OK", "count": 2, "results": [{"age": 27, "name": "Oz", "lactose_intolerant": true}, {"age": 29, "name": "Joe", "lactose_intolerant": false}]}
    >>> print(json.dumps(data, indent=2))  # With indention
    {
      "status": "OK",
      "count": 2,
      "results": [
    
        {
          "age": 27,
          "name": "Oz",
          "lactose_intolerant": true
        },
        {
          "age": 29,
    
          "name": "Joe",
          "lactose_intolerant": false
        }
      ]
    }
    

    4 异常捕获代替if判断

    Non-Pythonic

    if resource_exists():
        use_resource()
    

    Pythonic

    try:
        use_resource()
    except ResourceDoesNotExist:
        ...
    

    5 优雅的字典操作

    Pythonic

    # 读取键值,如果不存在不会抛出异常,直接返回Null
    >>> dict().get('missing key', 'failover value')
    'failover value'
    
    # 设置默认值
    >>> dict().setdefault('key', 'new value')
    'new value'
    >>> d = {'key': 'old value'}
    >>> d.setdefault('key', 'new value')
    'old value'
    
    # 或自动生成缺少键的初始值:
    >>> d = collections.defaultdict(int)
    >>> d['missing key'] += 1
    >>> d['missing key']
    1
    
    # 有序字典:
    >>> d = collections.OrderedDict()
    >>> d['x'] = 1
    >>> d['y'] = 1
    >>> list(d)
    ['x', 'y']
    >>> del d['x']
    >>> d['x'] = 1
    >>> list(d)
    ['y', 'x']
    

    6 上下文管理(with ** as ** )

    Non-Pythonic

    resource = allocate()
    try:
        resource.use()
    finally:
        resource.deallocate()
        
    # 打开/关闭文件
    f = open('data.txt')
    try:
        data = f.read()
    finally:
        f.close()
    

    Pythonic

    with allocate_resource() as resource:
        resource.use()
    
    # 打开/关闭文件
    with open('data.txt') as f:
        data = f.read()
    
    1. 最后一定不能忘记的操作是关闭文件,即使报错了也要 close。普通的方式是在 finnally 块中显示的调用 close 方法。
    2. 使用 with 语句,系统会在执行完文件操作后自动关闭文件对象。

    7 装饰器

    详细内容查看 Python高阶(二) - 按部就班了解装饰器

    8 快速交换

    Non-Pythonic

    a = 1
    b = 2
    tmp = a
    
    a = b
    b = tmp
    

    9 循环遍历区间元素(xrange)

    Non-Pythonic

    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
    

    10 带有索引位置的集合遍历(enumerate)

    Non-Pythonic

    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
    

    11 字符串连接(join)

    Non-Pythonic

    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)
    

    说明:

    1. join 方法整个过程只会产生一个字符串对象
    2. 使用+操作时,每执行一次+操作就会导致在内存中生成一个新的字符串对象

    12 合理使用列表

    Non-Pythonic

    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()
    
    1. 列表对象(list)是一个查询效率高于更新操作的数据结构,删除和插入需要对剩下的元素做移动操作
    2. deque 是一个双向队列的数据结构,删除元素和插入元素会很快

    13 序列解包

    Non-Pythonic

    p = 'vttalk', 'female', 30, 'python@qq.com'
    
    name = p[0]
    gender = p[1]
    age = p[2]
    email = p[3]
    

    Pythonic

    name, gender, age, email = p
    

    14 遍历字典的 key 和 value

    Non-Pythonic

    # 方法一
    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
    

    15 链式比较操作

    Non-Pythonic

    age = 18
    if age > 18 and x < 60:
        print("yong man")
    

    Pythonic

    if 18 < age < 60:
        print("yong man")
    

    16 行内判断 if/else 三目运算

    Non-Pythonic

    if gender == 'male':
        text = '男'
    else:
        text = '女'
    

    Pythonic

    text = '男' if gender == 'male' else '女'
    

    17 真值判断

    Non-Pythonic

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

    Pythonic

    if attr:
        do_something()
    
    if values:
        do_something()
    

    18 for/else语句

    Non-Pythonic

    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.")
    
    1. for else 是 Python 中特有的语法格式,else 中的代码在 for 循环遍历完所有元素之后执行。

    19 字符串格式化

    Non-Pythonic

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

    20 列表切片

    Non-Pythonic

    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[:]
    
    

    解释:
    列表元素的下标不仅可以用正数表示,还是用负数表示,最后一个元素的位置是 -1,从右往左,依次递减。

    P y t h o n
    0 1 2 3 4 5
    -6 -5 -4 -3 -2 -1

    21 善用生成器

    Non-Pythonic

    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
    

    生成器的好处就是无需一次性把所有元素加载到内存,只有迭代获取元素时才返回该元素

    22 用Counter来计数

    Non-Pythonic

    # Non-pythonic, ugly
    x_list = ['Ozil', 'Ramsey', 'Ozil', 'Ramsey', 'Giroud']
    x_dict = {}
    for x in x_list:
        if x in x_dict.keys():
            x_dict[x] += 1
        else:
            x_dict[x] = 1
    print(x_dict)
    

    Pythonic

    #Pythonic, elegant
    from collections import Counter
    
    x_list = ['Ozil', 'Ramsey', 'Ozil', 'Ramsey', 'Giroud']
    x_dict = Counter(x_list)
    print(x_dict)
    

    相关文章

      网友评论

        本文标题:Python高阶(三) - 我的Pythonic日记

        本文链接:https://www.haomeiwen.com/subject/qpcihxtx.html