name: inverse layout: true class: center, middle, inverse
su27
layout: false .left-column[
] .right-column[
-
高级
-
易学易读易维护
-
兼顾解释性和编译性的优点
-
面向对象
-
一些函数化编程的结构
-
高效快速,扩展库众多 ]
.left-column[
] .right-column[
-
动态语言
.python
a = 1 a = 'asdf'
-
强类型语言
.python
a = '1' a + 2 Traceback (most recent call last): File "", line 1, in TypeError: cannot concatenate 'str' and 'int' objects
-
一切皆对象
-
变量名只是一个名字,它指向一个对象
-
赋值操作其实是绑定操作
.python
(1).class int ]
-
.left-column[
]
.right-column[
-
python
-
ipython
-
help()
-
docstring
.python
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 | ]
.left-column[
] .right-column[
-
int:
100
,0x3e
-
long
- 并不是C或者其他编译类型语言的长整型
.python
import sys
sys.maxint 9223372036854775807
sys.maxint+1 9223372036854775808L
999999 ** 9 999991000035999916000125999874000083999964000008999999L
-
float:
1.1
-
complex:
(9+3j)
]
.left-column[
]
.right-column[
-
除法
.python
5 / 2 2 5.0 / 2 2.5 from future import division 5 / 2 2.5
-
其他运算 ]
.left-column[
]
.right-column[
-
字符串是不可变的
-
字符串的切片和成员操作
.python
s = 'hello douban' s[1:5] 'ello' s[:5] 'hello' s[-6:] 'douban'
'dou' in s True 'yah' in s False ]
.left-column[
]
.right-column[
-
字符串的连接与格式化
.python
print '哈' * 5 哈哈哈哈哈
'' + 'button' + '' 'button'
'%s' % ('red', 'button') 'button'
'{2}-{0}-{1}'.format('1', '4', '2013') '2013-1-4'
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' ]
.left-column[
]
.right-column[
-
字符串的连接与格式化
.python
#不好:
s = '' for i in seq: s += chr(i)
#好:
''.join(chr(i) for i in seq) ]
.left-column[
]
.right-column[
-
str:
-
'douban.com'
-
'\xe8\xb1\x86\xe7\x93\xa3'
-
unicode
-
u'\u8c46\u74e3'
-
转换
.python
'豆瓣' '\xe8\xb1\x86\xe7\x93\xa3'
'豆瓣'.decode('utf8') u'\u8c46\u74e3'
u'\u8c46\u74e3'.encode('utf8') '\xe8\xb1\x86\xe7\x93\xa3'
.left-column[
]
.right-column[
.left-column[
]
.right-column[
.left-column[
]
.right-column[
-
切片
-
append
,insert
,pop
,remove
,reverse
,sort
-
index
,count
(没有find) -
使用
list
模拟栈操作.python
stack = [3, 4, 5] stack.append(6) stack.append(7) stack [3, 4, 5, 6, 7] stack.pop() 7
-
使用
list.insert
模拟队列不如collections.deque
.python
from collections import deque queue = deque(["Eric", "John", "Michael"]) queue.append("Terry") # Terry arrives queue.popleft() # The first to arrive now leaves 'Eric' ]
.left-column[
] .right-column[
.python
>>> def f(x): return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]
.python
>>> seq = range(8)
>>> def add(x, y): return x+y
>>> map(add, seq, seq)
[0, 2, 4, 6, 8, 10, 12, 14]
.left-column[
] .right-column[
>>> squares = []
>>> for x in range(10):
... squares.append(x ** 2)
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> squares = map(lambda x: x ** 2, range(10))
>>> squares = [x ** 2 for x in range(10)]
.left-column[
] .right-column[
>>> 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]
>>> 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)]
# equals to:
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
.left-column[
] .right-column[
.python
>>> 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['CEO']
,pop
,popitem
,clear
-
get:
get
,has_key
(deprecated),keys
,values
,items
-
iter:
iterkeys
,itervalues
,iteritems
-
copy
,deepcopy
.python
Kid = {'h': '165', 'like': {'laptop': 'mac', 'book': []}} Kim = Kid.copy() Kim['like']['book'].append('LOTR') Kid['like'] {'laptop': 'mac', 'book': ['LOTR']} ]
.left-column[
] .right-column[
add
, discard
, remove
, clear
, copy
, update
union
(|), difference
(-), intersection
(*), symmetric_difference
(^)
.left-column[
] .right-column[
-
元组是不可变类型
.python
t = (1, 2) t[0] += 1 Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment
d = {} d[['a']] = 1 Traceback (most recent call last): File "", line 1, in TypeError: unhashable type: 'list' d[(1,2)] = 1
-
mutable: list, dict, set, 类实例
-
immutable: 数值类型, 字符串, tuple
.left-column[
] .right-column[
-
某种程度的可变
.python
d = (1, ['A', 'B']) d[1].append('C') d (1, ['A', 'B', 'C'])
-
单元素元组
.python
type((1)) <type 'int'> type((1,)) <type 'tuple'>
word = 'hello', len(word) 1 word ('hello',) ]
.left-column[
] .right-column[
-
Unpacking
result, = (1024,) result 1024
a, b = b, a ]
.left-column[
] .right-column[
Specialized container datatypes, providing
alternatives to Python’s general purpose built-in containers,
dict
, list
, set
, and tuple
.
.python
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
>>> c.subtract(d)
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
# An example:
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
.left-column[
] .right-column[
-
OrderedDict
.python
d = OrderedDict([('first', 1), ... ('second', 2), ... ('third', 3)]) d.items() [('first', 1), ('second', 2), ('third', 3)]
-
deque
-
defaultdict
-
namedtuple
.left-column[
] .right-column[
- if...elif...else
- 悬挂问题
C:
.c
if (x > 0)
if (y > 0)
printf('x,y available!\n');
else
printf('not available!\n');
python:
.python
if x > 0:
if y > 0:
print 'x,y available!'
else:
print 'not available!'
.left-column[
] .right-column[
-
条件判断与 bool()
.python toys = [] if len(toys) == 0: # 或者 if toys != [] print "boring..."
if not toys: print "boring..."
-
三元操作
x if condition else y
.python answer = 'yeah' if toys else 'no'
.left-column[
] .right-column[
-
while
-
for i in ...:
-
while和for都可以有else
.python def find_cat(cat, boxes): for box in boxes: if box.is_empty: continue elif cat in box: print "The cat is in", box break else: print "We have lost the cat."
break
,continue
,pass
, ... ]
.left-column[
] .right-column[
-
Example A
.python
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) ]
.left-column[
] .right-column[
-
所有异常都是
Exception
的子类- 除了
KeyboardInterrupted
和SystemExit
ValueError
,KeyError
, etc...
.python try: do_something() except KeyError: handle_key_error() except Exception, e: import traceback traceback.print_exc() finally: release_resources()
- 除了
-
raise
]
.left-column[
] .right-column[
-
不要做这样的事情
.python try: do_something() except: pass ]
.left-column[
] .right-column[
.python
# fibo.py
author = 'su27'
_author_age = 27
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while b < n:
print b,
a, b = b, a+b
-
import modules to use
.python
import fibo fibo.fib(1000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 fibo.author 'su27' fibo.name 'fibo' ]
.left-column[
] .right-column[
.python
def foo():
pass
foo.__doc__ = '呀,刚才忘了加上doc字符串'
foo.version = 0.2
.left-column[
] .right-column[
.python
>>> import fibo
>>> from fibo import fib, author
>>> from fibo import * # 绝大多数情况下要避免这样用
>>> author
'su27'
>>> _author_age
Traceback (most recent call last):
File or: name '_author_age' is not defined
.left-column[
] .right-column[
-
迭代器用起来是什么感觉?
.python for element in [1, 2, 3]: print element for key in {'one':1, 'two':2}: print key for key, value in {'one':1, 'two':2}.items(): print key, value for char in "123": print char for line in open("myfile.txt"): print line
-
xrange
和range
-
iterkeys
,iteritems
.left-column[
] .right-column[
-
for在这里做了什么?
.python
s = 'abc' it = iter(s) it <iterator object at 0x00A1DB50> it.next() 'a' it.next() 'b' it.next() 'c' it.next() Traceback (most recent call last): File "", line 1, in ? it.next() StopIteration ]
.left-column[
] .right-column[
-
能被迭代的是这样的对象: 把它传给iter(), 运行后会返回一个支持next()方法的对象
-
写一个:
.python class Reverse: """Iterator for looping over a sequence backwards.""" def init(self, data): self.data = data self.index = len(data) def iter(self): return self def next(self): if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data [self.index]
rev = Reverse('spam') iter(rev) <main.Reverse object at 0x00A1DB50> for char in rev: ... print char ]
.left-column[
] .right-column[
-
生成器是一种简单强大的创建迭代器的方法, 用yield代替return, 这样每次被调用next的时候,就会一直执行到下一次yield.
.python def reverse(data): for index in range(len(data)-1, -1, -1): yield data[index]
for char in reverse('red'): ... print char d e r
-
BTW...
.python for char in reversed(data): yield char
for char in data[::-1]: yield char ]
.left-column[
] .right-column[
-
把列表解析的方括号换成圆括号
.python
sum(x * y for x,y in zip(xvec, yvec)) # dot product 260
page = ('this is a big dog', 'this is a small cat')
words = set([word for line in page for word in line.split()])
words = {word for line in page for word in line.split()}
words = set(word for line in page for word in line.split())
words set(['a', 'this', 'big', 'is', 'dog', 'cat', 'small'])
.left-column[
] .right-column[
.python
def foo(value):
return value, value % 2
.python
def net_conn(host, port=80):
print "connect to %s:%s" % (host, port)
>>> net_conn('douban', 8080)
>>> net_conn(port=8080, host='douban')
.left-column[
] .right-column[
, port=80): print "connect to %s://%s:%s" % (scheme, host, port)
>>> net_conn('http', 'douban', host='8080')
>>> net_conn('douban', scheme='http', port=8080)
>>> net_conn(port=8080, host='douban', 'http')
>>> net_conn(port=8080, host='douban', scheme='http')
>>> net_conn(scheme='http', 'douban', port='8080')
>>> net_conn('http', port='8080')
>>> net_conn('http', 'douban')
>>> net_conn('http', 'douban', 8080, 'tcp')
.left-column[
] .right-column[
.python
def net_conn(scheme, host='douban', port=80):
print "connect to %s://%s:%s" % (scheme, host, port)
>>> net_conn('http', 'douban', host='8080')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: net_conn() got multiple values for keyword argument 'host'
>>> net_conn('douban', scheme='http', port=8080)
File "<stdin>", line 1
TypeError: net_conn() got multiple values for keyword argument 'scheme'
>>> net_conn(port=8080, host='douban', 'http')
File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg
>>> net_conn(port=8080, host='douban', scheme='http')
connect to http://douban:8080
.left-column[
] .right-column[
.python
def net_conn(scheme, host='douban', port=80):
print "connect to %s://%s:%s" % (scheme, host, port)
>>> net_conn(scheme='http', 'douban', port='8080')
File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg
>>> net_conn('http', port='8080')
connect to http://douban:8080
>>> net_conn('http', 'douban')
connect to http://douban:80
>>> net_conn('http', 'douban', 8080, 'tcp')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: net_conn() takes at most 3 arguments (4 given)
.left-column[
] .right-column[
-
用一个元组接受可变长默认参数
.python def func(arg1, arg2, *rest): print 'arg1:', arg1 print 'arg2:', arg2 for arg in rest: print 'extra arg:', arg
-
用一个字典接受可变长关键字参数
.python def func(arg1, arg2, **rest): print 'arg1:', arg1 print 'arg2:', arg2 for arg in rest: print 'extra arg: %s=%s' % (arg, rest[arg])
.left-column[
] .right-column[
.python
>>> def f(x, *args, **kwargs):
... print 'x:', x, 'args:', args, 'kwargs:', kwargs
...
>>> f(1)
x: 1 args: () kwargs: {}
>>> f(1, 2, 3)
x: 1 args: (2, 3) kwargs: {}
>>> f(1, 2, n=3)
x: 1 args: (2,) kwargs: {'n': 3}
.left-column[
] .right-column[
-
lambda [arg1[, arg2, ..., argN]]: expression
.python
sorted([('Bo', 24), ('Yi', 23), ('Si', 31)], key=lambda p: p[1]) [('Yi', 23), ('Bo', 24), ('Si', 31)]
map((lambda x: x+' me'), ['love', 'hate', 'kill']) ['love me', 'hate me', 'kill me']
reduce((lambda x,y: x+y), range(10)) 45 ] def net_conn(scheme, host='douban'"", line 1, in NameErr