python编程小技巧

python编程技巧总结:

在python的编程中会使用各种各样的语法,通过一些小技巧可以优化python代码,学习总结如下。学习参考地址:https://github.com/JeffPaine/beautiful_idiomatic_python

遍历一个序列

  1. python2:(xrange在遍历范围内创建一个迭代器,一次生成一个值,效率比range更高)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #bad:
    for i in [0, 1, 2, 3, 4, 5]:
    print i**2

    for i in range(6):
    print i**2

    #better:
    for i in xrange(6):
    print i**2
  2. python:(xrange更名为range,进行了优化)

    1
    2
    3
    4
    5
    6
    7
    color = ['red','green','blue','yello']
    #bad
    for i in range(len(color)):
    print(color[i])
    #better
    for co in color:
    print(co)

遍历倒序

  • python3:

    1
    2
    3
    4
    5
    6
    7
    color = ['red','green','blue','yello']
    #bad
    for i in range(len(color)-1,-1,-1):
    print(color[i])
    #better
    for co in reversed(color):
    print(co)

建立序列索引

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    colors = ['red', 'green', 'blue', 'yellow']

    #bad
    for i in range(len(colors)):
    print (i, '--->', colors[i])

    #better
    for i, color in enumerate(colors):
    print (i, '--->', color)

遍历两个序列

  1. python2:(用izip返回迭代)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    names = ['raymond', 'rachel', 'matthew']
    colors = ['red', 'green', 'blue', 'yellow']

    #bad
    n = min(len(names), len(colors))
    for i in range(n):
    print names[i], '--->', colors[i]

    for name, color in zip(names, colors):
    print name, '--->', color

    #better

    for name, color in izip(names, colors):
    print name, '--->', color
  2. python3:(用zip返回迭代)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    names = ['raymond', 'rachel', 'matthew']
    colors = ['red', 'green', 'blue', 'yellow']

    #bad
    n = min(len(names),len(colors))
    for i in range(n):
    print(names[i],'--->',colors[i])
    #batter
    for name, color in zip(names,colors):
    print(name,'--->',color)

遍历排序的序列

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    colors = ['red','green','blue','yellow']

    #Forward sorted order
    for color in sorted(colors):
    print(color)

    #Backwards sorted order
    for color in sorted(colors,reverse=True):
    print(color)

自定义遍历序列

  • python3:

    1
    2
    3
    colors = ['red', 'green', 'blue', 'yellow']

    print(sorted(colors,key=len))

遍历文件遇到指定字符退出

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #bad
    blocks = []
    while True:
    block = f.read(32)
    if block == '':
    break

    blocks.append(block)

    #better
    blocks = []
    if block in iter(partial(read,32),''):
    blocks.append(block)
    #iter是一个内置函数用来生产迭代器,partial的不断的读入文件中32字节,注意iter引入第二个参数,表示当读入的内容是''的时候,会触发生成器stop

函数遍历多出口问题

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #bad
    def find(seq, target):
    found = False
    for i, value in enumerate(seq):
    if value == target:
    found = True
    break
    if not found:
    return -1
    return i

    #better(for else结构)
    def find(seq, target):
    for i, value in enumerate(seq):
    if value == target:
    break
    else:
    return -1
    return i

遍历字典

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}

    for k in d:
    print(k)

    for k in d.keys():
    if k.startswith('a'):
    del d[k]
  • 遍历键和值:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}

    #bad
    for k in d:
    print(k, '-->', d[k])

    #batter
    for k,v in d.items():
    print(k,'--->',v)

构造字典

  • python3:

    1
    2
    3
    4
    5
    names = ['raymond', 'rachel', 'matthew']
    colors = ['red', 'green', 'blue']

    d = dict(zip(names, colors))
    print(d)

字典的统计

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    colors = ['red', 'green', 'red', 'blue', 'green', 'red']

    #bad
    d = {}
    for color in colors:
    if color not in d:
    d[color] = 0
    d[color] += 1
    print(d)

    #batter
    s = {}
    for color in colors:
    s[color] = s.get(color,0) + 1
    print(d)

对序列的值根据元素长度进行分组

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    names = ['raymond', 'rachel', 'matthew', 'roger',
    'betty', 'melissa', 'judith', 'charlie']
    #bad
    d = {}
    for name in names:
    key = len(name)
    if key not in d:
    d[key] = []
    d[key].append(name)

    d = {}
    for name in names:
    key = len(name)
    d.setdefault(key, []).append(name)
    print(d)

    #better
    s = {}
    for name in names:
    key = len(name)
    s.setdefault(key, []).append(name)
    print(s)

字典遍历倒序

  • python3:(使用popitem)

    1
    2
    3
    4
    5
    d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}

    while d:
    key, value = d.popitem()
    print (key, '-->', value)

字典链接

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import argparse
    import os
    import collections

    #bad
    defaults = {'color': 'red', 'user': 'guest'}
    parser = argparse.ArgumentParser()
    parser.add_argument('-u', '--user')
    parser.add_argument('-c', '--color')
    namespace = parser.parse_args([])
    command_line_args = {k:v for k, v in vars(namespace).items() if v}

    d = defaults.copy()
    d.update(os.environ)
    d.update(command_line_args)
    print(d)

    #better
    d = collections.ChainMap(command_line_args, os.environ, defaults)
    print(d)

    #关于Python中ChainMap的使用:http://blog.topspeedsnail.com/archives/9726

使用关键字提高代码清晰度

  • python3:

    1
    2
    3
    4
    5
    #bad
    twitter_search('@obama', False, 20, True)

    #Better
    twitter_search('@obama', retweets=False, numtweets=20, popular=True)

展开序列

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    p = ['Leo','Xin','30','coder']

    #bad
    fname = p[0]
    lname = p[1]
    age = p[2]
    email = p[3]

    #better
    fname,lname,age,email = p

交换变量

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def fibonacci(n):
    x = 0
    y = 1
    for i in range(n):
    print(x)
    t = y
    y = x + y
    x = t

    def fibonacci(n):
    x, y = 0, 1
    for i in range(n):
    print (x)
    x, y = y, x + y

更新序列

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import collections
    names = ['raymond', 'rachel', 'matthew', 'roger',
    'betty', 'melissa', 'judith', 'charlie']
    #bad
    del names[0]
    names.pop(0)
    names.insert(0, 'mark')

    #Better
    names = collections.deque(['raymond', 'rachel', 'matthew', 'roger',
    'betty', 'melissa', 'judith', 'charlie'])
    del names[0]
    names.popleft()
    names.appendleft('mark')
    print(names)

    #利用collections模块里面的双向队列,会更简洁

使用线程锁

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import threading

    lock = threading.Lock()

    #bad
    lock.acquire()
    try:
    print ('Critical section 1')
    print ('Critical section 2')
    finally:
    lock.release()

    #Better
    with lock:
    print ('Critical section 1')
    print ('Critical section 2')

修改for循环语句

  • python3:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    result = []
    #bad
    for i in range(10):
    s = i ** 2
    result.append(s)
    print (sum(result))

    #Better
    print (sum(i**2 for i in range(10)))