Skip to content
Tony Zhu edited this page Jan 21, 2015 · 9 revisions

Python ABC

此文档,参考引用了豆瓣su27老师以前写的内容


Python: 优雅而健壮的编程语言

  • 高级

  • 兼顾解释性和编译性的优点

  • 各种编程范式

  • 扩展库众多


  • 动态语言
>>> a = 1
>>> a = 'asdf'
  • 强类型语言
>>> a = '1'
>>> a + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
  • 一切皆对象
    • 变量名只是一个名字,它指向一个对象
    • 赋值操作其实是绑定操作
>>> (1).__class__
int

工具

  • python:解释器

  • ipython:漂亮的交互式解释器

  • help():帮助文档

  • docstring:代码内帮助文档

>>> help(list)

Help on class list in module __builtin__:

class list(object)
 |  list() -> new empty list
 |  list(iterable) -> new list initialized from iterable's items
 |
 |  Methods defined here:
 |
 |  __add__(...)
 |      x.__add__(y) <==> x+y
 |
 |  __contains__(...)
 |      x.__contains__(y) <==> y in x
 |

Data Structures


数值

  • int: 100 , 0x3e

  • long

    • 并不是C或者其他编译类型语言的长整型
>>> import sys

>>> sys.maxint
>>> 9223372036854775807

>>> sys.maxint + 1
>>> 9223372036854775808L

>>> 999999 ** 9
>>> 999991000035999916000125999874000083999964000008999999L
  • float: 1.1

  • complex: (9+3j)


数值运算

  • 除法
>>> 5 / 2
2
>>> 5.0 / 2
2.5

>>> from __future__ import division
>>> 5 / 2
2.5
>>> 5 // 2
2
  • 其他运算

String

  • 字符串是不可变的
>>> s = 'python'
>>> s[0]
'p'
>>> s[0] = 'c' # TypeError
  • 字符串的切片和成员操作
>>> s = 'hello world!'
>>> s[1:5]
'ello'
>>> s[:5]
'hello'
>>> s[-6:]
'world!'

>>> 'world' in s
True
>>> 'haha' in s
False

String

  • 字符串的连接与格式化
>>> print '哈' * 5
哈哈哈哈哈

>>> '<span class="' + 'red' + '">' + 'button' + '</span>'
'<span class="red">button</span>'

>>> '<span class="%s">%s</span>' % ('red', 'button')
'<span class="red">button</span>'

>>> '{2}-{0}-{1}'.format('1', '4', '2013')
'2013-1-4'

>>> '{}:{}:{day}'.format(2009, 4, day='Sunday') # python 2.7
'2009:4:Sunday'

>>> coord = (3, 5)
>>> 'X: {0[0]};  Y: {0[1]}'.format(coord)
'X: 3;  Y: 5'

>>> coord = {'latitude': '37.24N', 'longitude': '-115.81W'}
>>> 'Target: {latitude}, {longitude}'.format(**coord)
'Target: 37.24N, -115.81W'

String

  • 字符串的连接与格式化
# 不好:

s = ''
for i in seq:
    s += chr(i)

# 好:

''.join(chr(i) for i in seq)

String

  • str:

  • 'python'

  • '\xe4\xbd\xa0\xe5\xa5\xbd'

  • unicode

  • u'\u4f60\u597d'

  • 转换

>>> '你好'
'\xe4\xbd\xa0\xe5\xa5\xbd'

>>> '你好'.decode('utf8')
u'\u4f60\u597d'

>>> u'\u4f60\u597d'.encode('utf8')
'\xe4\xbd\xa0\xe5\xa5\xbd'

字符串的方法

  • find, index, rfind, rindex, count
  • startswith, endswith, isalpha, isdigit, isalnum, islower, isupper, isspace
  • encode, decode, lower, upper, strip, lstrip, rstrip, replace
  • split, rsplit, splitlines
  • join

容器

  • tuple: (1, 'hello') , (1,)
  • list: [1, 2, 3, 4, 5]
  • dict: {'Teacher': 'tony', 'Team Members': ['不比', '字母同学', ...]}
  • set: set([1, 2, 3])

list

  • 切片
  • append , insert , pop, remove, reverse , sort
  • index , count (没有find)
  • 使用 list 模拟栈操作
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7

list

  • 改变一个可变对象的方法,通常没有返回值
>>> li = ['n', 'b', 'a']
>>> li.sort()
>>> li.reverse()
>>>

# 与不可变对象比较:
>>> 'This is it.\n'.strip().upper()
'THIS IS IT.'

# 如果想要返回:
>>> sorted(li)
['a', 'b', 'n']

FP tools for list

filter

>>> def f(x): return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]

map

>>> seq = range(8)
>>> def add(x, y): return x+y
>>> map(add, seq, seq)
[0, 2, 4, 6, 8, 10, 12, 14]

列表解析

A.

>>> squares = []
>>> for x in range(10):
...     squares.append(x ** 2)
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

B.

>>> squares = map(lambda x: x ** 2, range(10))

C. (list Comprehension)

>>> squares = [x ** 2 for x in range(10)]

列表解析: 多变量及过滤条件

exam A: flatten a list

>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

exam B:

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

# 可以这样写:
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]

dict

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}

# Dict Comprehensions
>>> {x: x ** 2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
  • set: d['name'] = 'Jim', update, setdefault
  • delete: del d['Teacher'], pop, popitem, clear
  • get: get, has_key (deprecated), keys, values, items
  • iter: iterkeys, itervalues, iteritems
  • copy, deepcopy
>>> Kid = {'h': '170', 'like': {'laptop': 'mac', 'book': []}}
>>> Kim = Kid.copy()
>>> Kim['like']['book'].append('LOTR')
>>> Kid['like']
{'laptop': 'mac', 'book': ['LOTR']}

set

set的修改:

add, discard, remove, clear, copy, update

set的运算:

union(|), difference(-), intersection(*), symmetric_difference(^)

子集的判断:

issubset, issuperset, &gt;, &lt;


tuple

  • 元组是不可变类型
# 不可赋值
>>> t = (1, 2)
>>> t[0] += 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

# 可做dict的key
>>> d = {}
>>> d[['a']] = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> d[(1,2)] = 1
  • mutable: list, dict, set, 类实例
  • immutable: 数值类型, 字符串, tuple

tuple

  • 某种程度的可变
>>> d = (1, ['A', 'B'])
>>> d[1].append('C')
>>> d
(1, ['A', 'B', 'C'])
  • 单元素元组
>>> type((1))
<type 'int'>
>>> type((1,))
<type 'tuple'>

>>> word = 'hello',
>>> len(word)
1
>>> word
('hello',)

tuple

  • Unpacking
>>> result, = (1024,)
>>> result
1024

>>> a, b = b, a

# 注意,其他iterable也是可以unpack的
>>> a, b = range(2)
>>> a, b = xrange(2)
>>> a, b = (i for i in range(2))
>>> a, b = {"a":1, "b":2}
>>> a, b = {"a":1, "b":2}.iteritems()

控制流


分支

  • if...elif...else
  • 悬挂问题

C:

if (x > 0)
    if (y > 0)
        printf('both available!\n');
else
    printf('x not available!\n');

python:

if x > 0:
    if y > 0:
        print 'both available!'
else:
    print 'x not available!'

分支

  • if(not)通过计算bool()来判断,因此可以直接利用对象的bool()值
toys = []
# if len(toys) == 0: 或者 if toys != [] 不好
if not toys:
    print "boring..."
  • 三元操作 x if condition else y
answer = 'yeah' if toys else 'no'

循环

  • while
  • for i in ...
  • break, continue, pass, ...
  • while和for都可以有else
def find_cat(cat, boxes):
    for box in boxes:
        if box.isempty():
            continue
        elif cat in box:
            print "The cat is in", box
            break
    else:
        print "We have lost the cat."

循环

  • Example A
# 不好
for i in range(len(seq)):
    foo(seq[i], i)
# 好:
for i, item in enumerate(seq):
    foo(item, i)
  • Example B
# 不好:
for i in xrange(len(seq1)):
    foo(seq1[i], seq2[i])
# 好:
for i, j in zip(seq1, seq2):
    foo(i, j)

for i, j in itertools.izip(seq1, seq2):
    foo(i, j)

函数

基础的函数

def funcA():
    ''' 无参数,无返回'''
    pass

def funcB(msg):
    ''' 有参数, 无返回 '''
    print msg

def funcC(msg):
    ''' 有参数, 又返回'''
    return msg * 2

def funcD(msg, times):
    ''' 多个参数 '''
    for i in range(times):
        print msg

def funcE(msg, times):
    ''' 多个参数,多个返回 '''
    new_msg = msg * times
    return new_msg, True


>>>funcA()
>>>funcB('hello world')
hello world
>>>new_msg = funcC('count a sheep ')
>>>print new_msg
count a sheep count a sheep 
>>>funcD('哈', 5)





>>>new_msg, status = funcE('哈', 5)
>>>print new_msg, status
哈哈哈哈哈哈 True
    

书目推荐

  • a byte of python, 非常简单
  • python核心编程, 入门必备看过都说好
  • python cookbook, 进阶可以瞧瞧
  • 可爱的Python, 国人作品,我没看过
  • python源码剖析, 进阶成高手必备

Tips:

  • 养成好的习惯:PEP8
  • 提问的艺术:先Google,再Stackoverflow,再问周围的人
  • 使用github:1.代码版本控制;2.发现更多优秀的Code和Coder; 3.看Tony写这些东西。