Python学习之旅之函数

这次Python学习参考的是Python基础教程,前面由于有一些Java基础,所以看的还比较顺利,然而到了函数这章就不太顺了,特别是参数这节。

下面对函数做一下简单的讲解。

假设需要编写一个存储联系人姓名并且能用名字、中间名、或姓查找联系人的程序,可以使用下面的数据结构:

storage = {}
storage['first'] = {}
storage['middle'] = {}
storage['last'] = {}
storage是一个有三个键(‘first’,‘middle’,‘last’)的字典,每个键下面又存储一个子字典,子字典中可以使用名字(名字、中间名或姓)作为键,插入联系人姓名的列表作为值,比如将作者的名字Magnus Lie Hetland插入这个数据结构中:

author = 'magnus Lie Hetland'
storage['first']['Magnus'] = [author]
storage['middle']['Lie'] = [author]
storage['last']['Hetland'] = [author]
每个键下面都存储了一个以人名组成的列表,现在如果想得到所用中间名为Lie的人则可进行如下操作:

print storage['middle']['Lie']
结果为: ['magnus Lie Hetland']

其实我看到这里就有点混乱了,这种字典中含字典的不太好理解,所以现在将storage输出看一下它的整体结构:

print storage
结果为(字典的键没有顺序):

{
	'middle': 
		{
			'Lie': ['magnus Lie Hetland']
		},
	 'last': 
		{
			'Hetland': ['magnus Lie Hetland']
		},
	 'first': 
		{
			'Magnus': ['magnus Lie Hetland']
		}
}

这样起来就清楚多了。

现在再在storage中加入作者姐姐的名字Anne Lie Hetland:

sister = 'Anne Lie Hetland'
storage['first'].setdefault('Anne', []).append(sister)
storage['middle'].setdefault('Lie', []).append(sister)
storage['last'].setdefault('Hetland', []).append(sister)
现在storage的结构为

{
	'middle': {
		'Lie': ['magnus Lie Hetland', 'Anne Lie Hetland']
	}, 
	'last': {
		'Hetland': ['magnus Lie Hetland', 'Anne Lie Hetland']
	},
	 'first': {
		'Anne': ['Anne Lie Hetland'],
		'Magnus': ['magnus Lie Hetland']
	}
}
现在storage中姓Hetland的有两个人,名为Anne的有一个人,名为Magnus的有一个人。现在应该清楚这个数据结构的存储方式了吧。

(我要吐槽一下我的进度了,以上内容来自于2017年3月21日,现在是2017年3月22日晚11点50分,估计一会发表完就得23号了吧......)

如果要继续增加联系人的话以上写法就会变得臃肿且笨拙不堪了,这个过程可以用函数来实现:

首先是初始化数据结构的函数:

def init(data):
    data['first'] = {}
    data['middle'] = {}
    data['last'] = {}
调用及结果如下:

storage = {}
init(storage)
{'middle': {}, 'last': {}, 'first': {}}  # 结果
在编写存储名字的函数前,先写一个获得名字的函数:

def lookup(data, label, name):
    return data[label].get(name)
即返回字典data中键为label的字典中名为name的键对应的值。

现在开始写存储名字的函数:

def store(data, full_name):
    names = full_name.split()  # 将名字拆分成一个列表
    if len(names) == 2:  # 如果名字长度为2(只有first和last),插入一个空字符串作为中间名
        names.insert(1, '')
    labels = 'first', 'middle', 'last'  # 将字符串first、middle、last作为元祖存储在labels中,方便一会遍历的时候使用
    for label, name in zip(labels, names):  # 使用zip函数联合标签和名字,对于每一个(lable,name)对,进行如下处理
        people = lookup(data, label, name)  # people为键name对应的值
        if people:			    # 如果people不为空,证明已经存在name这个键了,所以直接把名字添加到这个键下即可	
            people.append(full_name)
        else:				    # 如果people为空,则现在还不存在name这个键,所以以name为键,full_name(想要加入的名字)为值创建一个新的列表
            data[label][name] = [full_name]
之前的添加过程就可以表示为:

MyNames = {}
init(MyNames)
store(MyNames, 'magnus Lie Hetland')
store(MyNames, 'Anne Lie Hetland')
print lookup(MyNames, 'middle', 'Lie')

现在到了我认为这章的重点——参数。为止参数和关键字参数就不做介绍了,我主要想讲一下收集参数。

如果想给函数提供任意多的参数可以向如下这样定义函数:

def print_params(*params):
    print params

调用及结果如下:

print_params('1')
print_params(1, 2, 3)
# 结果
('1',)
(1, 2, 3)
参数前的星号将所有值放置在同一个元祖中。可以说是将一个值收集起来然后使用。

现有如下函数:

def print_params2(title, *params):
    print title
    print params
# 调用
print_params2('Params:', 1, 2, 3)
# 结果
Params:
(1, 2, 3)
星号可以理解为收集其余的位置参数,如果不提供任何参数,params就是个空元祖,输出结果为{}。
但它不能处理关键字参数,如:

# 调用print_params2
print_params2('Params:', p1=1)
# 错误为
TypeError: print_params2() got an unexpected keyword argument 'p1'
如果想要处理关键字操作则需要写两个星(“**“):

def print_params3(**params):
    print params
调用及结果为:

print_params3(x=1, y=2, z=3)
# 结果
{'y': 2, 'x': 1, 'z': 3}
各种参数也可放在一起混合使用:

# 函数
def print_params4(x, y, z=3, *poster, **params):
    print x, y, z
    print poster
    print params
# 调用
print_params4(1, 2, 3, 4, 5, 6, m=7, n=8)
# 结果
1 2 3
(4, 5, 6)
{'m': 7, 'n': 8}

现在如果想一次性存储多个名字时就可以将store改写为:
def store(data, *full_names):
    for full_name in full_names:
        names = full_name.split()
        if len(names) == 2:
            names.insert(1, '')
        labels = 'first', 'middle', 'last'
        for label, name in zip(labels, names):
            people = lookup(data, label, name)
            if people: 
                people.append(full_name)
            else:
                data[label][name] = [full_name]
函数调用就可以写为store(MyNames,‘magnus Lie Hetland'’,‘Anne Lie Hetland’)结果不变。


(现在是3月23日凌晨1点12分,终于为我的Python坑填上了第一把土,没想到第一篇博就写了这么长时间,不知道我还能坚持多久......总之,加油吧!)











 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值