Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1102157
  • 博文数量: 165
  • 博客积分: 5957
  • 博客等级: 大校
  • 技术积分: 2015
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-24 15:04
文章分类

全部博文(165)

文章存档

2014年(10)

2013年(14)

2012年(9)

2011年(22)

2010年(17)

2009年(17)

2008年(26)

2007年(34)

2006年(16)

我的朋友

分类: Python/Ruby

2007-10-15 22:00:11

TASK:
    decide to write a Python program to manage your people -- keep records in a database -- to permanently store lists of people's attributes on your computer.
 
Keyword:
    lists,Field labels
 
practise过程:

-----lists-----
>>> bob = ['Bob Smith', 42, 30000, 'software']
>>> sue = ['Sue Jones', 45, 40000, 'music']
>>> bob[0], sue[2]
('Bob Smith', 40000)
>>> bob[0].split()[-1]
'Smith'
>>> sue[2] *= 1.25
>>> sue
['Sue Jones', 45, 50000.0, 'music']
>>> people = [bob, sue]
>>> for person in people:
...     print person
...
['Bob Smith', 42, 30000, 'software']
['Sue Jones', 45, 50000.0, 'music']
>>> people[1][0]
'Sue Jones'
>>> for person in people:
...     print person[0].split()[-1]
...     person[2] *=1.20
...
Smith
Jones
>>> for person in people: print person[2]
...
36000.0
60000.0

>>> pays = [person[2] for person in people]
>>> pays
[36000.0, 60000.0]
>>> pays = map((lambda x: x[2]), people)   #ditto
【map是Python的内置函数,用于对线形容器执行函数化操作,具体来说,是把对某个(或多个)序列中所有元素的操作结果映射到另一个序列中。
>>> help(map)
Help on built-in function map in module __builtin__:

map(...)
    map(function, sequence[, sequence, ...]) -> list
   
    Return a list of the results of applying the function to the items of the argument sequence(s).  If more than one sequence is given, the function is called with an argument list consisting of the corresponding item of each sequence, substituting None for missing values when not all sequences have the same length.  If the function is None, return a list of the items of the sequence (or a list of tuples if more than one sequence).

== lambda ==

和数学中的 λ 一样, python的函数编程体系中有一个 lambda 语句, 用来生成函数, 一般这样的函数称为匿名函数.

例如:
{{{
#!python
lambda x: x+1
}}}
就生成了一个函数 λ(x) = x+1.

具有可以在python的解释器中试试:

{{{
#!python
>>> lambda x: x+1 # 生成一个匿名函数 λ(x) = x+1
at 0x00C99770>
>>> f = lambda x: x+1 # 将这个函数绑定名字 'f'
>>> f(1) # 调用 'f'
2
}}}

lambda的具体语法是:

lambda [parameter_list]: expression

parameter_list 是参数表,
expression 是后面跟的表达式, lambda本身是个运算符, 作用在这两个元素上产生一个匿名函数, 类似于以下函数定义:

{{{#!python
def name(parameter_list):
    return expression
}}}

expression 是一个合法的python表达式,
显然 expression 中的变量量除了在 parameter_list 中的外必须是已知的.


注意experssion中是不能用print语句的, 要想产生输出的话可以用sys.stdout.write()等函数.


下面会不断给出 lambda 的例子

== 高阶函数 ==
所谓的高阶函数其实是一组以函数为参量的函数. 下面介绍 Python 中的具体形式.

=== map ===
map是最基本的函数, 搞懂了map其他函数就很容易搞懂.

map 的定义:

map( function, list, ...)

将函数function作用到 list 的每个元素上, 将结果组成一个列表返回.
如果参数列表有多个, 函数应该是有多参数的, 每个分量取各列表上的对应值, 如果有列表比其他列表短, 不足部分当作 None .

这里list可以是任意序列(sequence), 例如列表(list) , 元组(tuple)等.

例如:

{{{
#!python
>>> a = range(5);
>>> b = range(4);
>>> map(lambda x, y: (x, y) , a, b) # lambda x,y 接受两个参数, 生成个包含这两个参数的tuple.
[(0, 0), (1, 1), (2, 2), (3, 3), (4, None)]
}}}

另一种多参数调用的方法是组合列表:
map(lambda (arg1, ..., argn): expression, multiple_list),
multiple_list 是一个列表, 他的元素还是一个列表, 即参数列表.
这种方法实质还是单参数调用(这个不一定要完全理解).

例如:
{{{
#!python
>>> ml = [[0, 1], [2, 3], [3, 4]]
>>> map(lambda (x,y): x+y , ml) # lambda (x,y): x+y 接受一个有两元元组(tuple), 计算他们的和.
[1, 5, 7]
}}}

如果map 的第一个参数, 即function等于None, 则默认为恒等变换.
例:
{{{
#!python
>>> a = range(3)
>>> map(None , a)
[0, 1, 2]
}}}

== reduce ==
reduce( function, sequence[, initializer])

将函数function从左到右作用在序列的每个元素上, 函数function为二元函数, 第一个变量为上次计算所得结果,第二个变量为列表元素. 具体得:

{{{
#!python
>>> reduce(lambda x,y: x+y , [1,2,3,4,5]) # 相当于 ((((1+2)+3)+4)+5)
15
}}}

整个计算过程就像列表在不断缩减一样.

initializer为初值.
例如:
{{{
>>> reduce(lambda x,y: x+y , [1,2,3,4,5], 10) # 相当于(((((10+1)+2)+3)+4)+5)
25
}}}


== filter ==
filter( function, list)

filter 过滤器.

从list的元素中构造一个列表, 这个列表的元素依次是list中使function为真的元素.
list可以是任意序列, 如列表(List)和元组(Tuple)等, 或支出迭代子的容器, 或者迭代子
例子:
{{{
#!python
>>> filter(lambda x: x>5 , [10,1,5,6,7]) # 将列表中小于5的元素滤去.
[10, 6, 7]
}}}

和map一样, 若function是None , 则代为恒等函数, 这样将滤去所有取值为false的元素(包括0和None).


>>> pays
[36000.0, 60000.0]
>>> sum(person[2] for person in people)
96000.0
>>> people.append(['Tom', 50, 0, None])
>>> len(people)
3
>>> people[-1][0]
'Tom'

-----Field labels-----

>>> NAME, AGE, PAY = range(3)
>>> bob = ['Bob Smith', 42, 10000]
>>> bob[NAME]
'Bob Smith'
>>> PAY, bob[PAY]
(2, 10000)
>>> bob = [['name', 'Bob Smith'], ['age', 42], ['pay', 10000]]
>>> sue = [['name', 'Sue Jones'], ['age', 45], ['pay', 20000]]
>>> people = [bob, sue]
>>> for person in people:
...     print person[0][1], person[2][1]
...
Bob Smith 10000
Sue Jones 20000
>>> [person[0][1] for person in people]
['Bob Smith', 'Sue Jones']
>>> for person in people:
...     print person[0][1].split()[-1]
...     person[2][1] *= 1.10
...
Smith
Jones
>>> for person in people: print person[2]

['pay', 11000.0]
['pay', 22000.0]
>>> for person in people:
...     for (name, value) in person:
...         if name == 'name': print value
...    
Bob Smith
Sue Jones
>>> def field(record, label):
...     for (fname, fvalue) in record:
...         if fname == label:
...             return fvalue
...    
>>> field(bob, 'name')
'Bob Smith'
>>> field(sue, 'pay')
22000.0

>>> for rec in people:
...     print field(rec, 'age')
...    
42
45
 

-----Use Dictionaries-----

>>> bob = {'name': 'Bob Smith', 'age': 42, 'pay': 30000, 'job': 'dev'}
>>> sue = {'name': 'Sue Jones', 'age': 45, 'pay': 40000, 'job': 'mus'}
>>> bob['name'], sue['pay']
('Bob Smith', 40000)
>>> bob['name'].split( )[-1]
'Smith'
>>> sue['pay'] *= 1.10
>>> sue['pay']
44000.0

Other ways to make dictionaries
>>> bob = dict(name='Bob Smith', age=42, pay=30000, job='dev')
>>> bob
{'pay': 30000, 'job': 'dev', 'age': 42, 'name': 'Bob Smith'}

>>> M = [[1, 2, 3],           # 3x3, 2-dimensional
                 [4, 5, 6],
                 [7, 8, 9]]
>>> M = [[2, 2, 2],
                 [3, 3, 3],
                 [4, 4, 4]]
>>> for i in range(3):
...     for j in range(3):
...         print M[i][j] * N[i][j],
...     print
2 4 6
12 15 18
28 32 36

>>> tbl = []
>>> for i in range(3):
...     row = []
...     for j in range(3):
...         row.append(M[i][j] * N[i][j])
...     tbl.append(row)
...    
>>> tbl
[[2, 4, 6], [12, 15, 18], [28, 32, 36]]

>>> [[M[i][j] * N[i][j] for j in range(3)] for i in range(3)]
>>> [[x * y for x, y in zip(row1, row2)] for row1, row2 in zip(M, N)]

>>> import sys
>>> [x for x in dir(sys) if x.startswith('getr')]
['getrecursionlimit', 'getrefcount']

>>> lines = [line.rstrip( ) for line in open('backup/install.log')]         
>>> lines[0]
'Installing 742 packages'
>>> len(lines)
1490

>>> sue = {}
>>> sue['name'] = 'Sue Jones'
>>> sue['age'] = 45
>>> sue['pay'] = 40000
>>> sue['job'] = 'mus'
>>> sue
{'job': 'mus', 'pay': 40000, 'age': 45, 'name': 'Sue Jones'}

Zipping
>>> names = ['name', 'age', 'pay', 'job']
>>> values = ['Sue Jones', 45, 40000, 'mus']
>>> zip(names, values)
[('name', 'Sue Jones'), ('age', 45), ('pay', 40000), ('job', 'mus')]
>>> sue = dict(zip(names, values))
>>> sue
{'job': 'mus', 'pay': 40000, 'age': 45, 'name': 'Sue Jones'}

>>> fields = ('name', 'age', 'job', 'pay')
>>> record = dict.fromkeys(fields, '?')
>>> record
{'job': '?', 'pay': '?', 'age': '?', 'name': '?'}

>>> people = [bob, sue]
>>> for person in people:
...     print person['name'], person['pay']
...    
Bob Smith 30000
Sue Jones 44000.0
>>> for person in people:
...     if person['name'] == 'Sue Jones':
...         print person['pay']
...    
44000.0
>>> names = [person['name'] for person in people]
>>> names
['Bob Smith', 'Sue Jones']
>>> map((lambda x: x['name']), people)
['Bob Smith', 'Sue Jones']
>>> sum(person['pay'] for person in people)
74000.0
>>> for person in people:
...     print person['name'].split( )[-1]
...     person['pay'] *= 1.10
...    
Smith
Jones 
>>> for person in people: print person['pay']
33000.0
48400.0

Nested structures
>>> bob2 = {'name': {'first': 'Bob', 'last': 'Smith'},
...          'age':  42,
...          'job':  ['software', 'writing'],
...          'pay':  (40000, 50000)}
>>> bob2['name']
{'last': 'Smith', 'first': 'Bob'}
>>> bob2['name']['last']
'Smith'
>>> bob2['pay'][1]
50000
>>> for job in bob2['job']: print job
...
software
writing
>>> bob2['job'][-1]
'writing'
>>> bob2['job'].append('janitor')
>>> bob2
{'job': ['software', 'writing', 'janitor'], 'pay': (40000, 50000), 'age': 42, 'name': {'last': 'Smith', 'first': 'Bob'}}

Dictionaries of dictionaries
>>> db = {}
>>> db['bob'] = bob
>>> db['sue'] = sue
>>> db['bob']['name']
'Bob Smith'
>>> db['sue']['pay'] = 50000
>>> db['sue']['pay']
50000
>>> db
{'bob': {'pay': 33000.0, 'job': 'dev', 'age': 42, 'name': 'Bob Smith'}, 'sue': {'job': 'mus', 'pay': 50000, 'age': 45, 'name': 'Sue Jones'}}
>>> for key in db:
...     print key, '=>', db[key]['name']
...    
bob => Bob Smith
sue => Sue Jones
>>> for key in db:
...     print key, '=>', db[key]['pay']
...    
bob => 33000.0
sue => 50000
>>> for key in db:
...     print db[key]['name'].split( )[-1]
...     db[key]['pay'] *= 1.10
...    
Smith
Jones
>>> for record in db.values( ): print record['pay']
36300.0
55000.0
>>> x = [db[key]['name'] for key in db]
>>> x
['Bob Smith', 'Sue Jones']
>>> x = [rec['name'] for rec in db.values( )]
>>> x
['Bob Smith', 'Sue Jones']

>>> db['tom'] = dict(name='Tom', age=50, job=None, pay=0)
>>> db['tom']
{'pay': 0, 'job': None, 'age': 50, 'name': 'Tom'}
>>> db['tom']['name']
'Tom'
>>> db.keys( )
['bob', 'sue', 'tom']
>>> len(db)
3


利用格式化文件保存记录

>>> print open('data.txt').read( )
001.1 002.2 003.3
010.1 020.2 030.3 040.4
100.1 200.2 300.3

>>> sums = {}
>>> for line in open('data.txt'):
        cols = [float(col) for col in line.split( )]
        for pos, val in enumerate(cols):
            sums[pos] = sums.get(pos, 0.0) + val

>>> for key in sorted(sums):
        print key, '=', sums[key]

0 = 111.3
1 = 222.6
2 = 333.9
3 = 40.4

>>> sums
{0: 111.3, 1: 222.59999999999999, 2: 333.90000000000003,
3: 40.399999999999999}

顺便看一下遍历的方法:
最普通的:

for item in sequence:
    process(item)

这样遍历取不到item的序号i,所有就有了下面的遍历方法:

for index in range(len(sequence)):
    process(sequence[index])

其实,如果你了解内置的enumerate函数,还可以这样写:

for index, item in enumerate(sequence):
    process(index, item)

阅读(2058) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~