Python 函数



# coding = utf-8

#########################################################################
# 1.def 自定义函数

# 自定义斐波那契函数
def fibs(num):
    result = [0, 1]
    for i in range(num-2):
        result.append(result[-2] + result[-1])
    return  result

print(fibs(4))
print()

# 2. 给函数编写文档
# 将注释写在函数的开头,这个字符串被称为文档字符串 将作为函数的一部分存储起来
# 可通过函数名._doc_来访问
# 自定义平方函数
def square(x):
    'Calculates the square of x'
    return x * x
print(square.__doc__)
print()

# 3.所有函数都有返回值,如果没有指定返回值,那将返回None
# 如果函数里有if语句,一定要确保所有的分支都返回一样的类型

# 4.参数魔法
# 4.1 位置参数
# 在函数内部给参数赋值,对外部没有任何影响
# 但在函数内部修改了变量关联的列表或字典,对外部被关联的列表或字典是有影响
# 字符串 元组 数 类型的参数 是不可变的,在函数内部对其修改 不会影响外部
def initdata(data):
    data['first'] = {}
    data['middle'] = {}
    data['last'] = {}

def lookup(data, label ,name):
    return data[label].get(name)

def store(data, full_name):
    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]


myNames = {}
initdata(myNames)
store(myNames, 'Magnus Lie Hetland')
store(myNames, 'Tana Lie Smith')
store(myNames, 'Joe Smith')
print(lookup(myNames, 'last', 'Smith'))

# 如果参数是字符串 数 元组 等不可变参数,而在函数外部又需要改变该参数
# 可以在外部对参数以函数返回值进行重新赋值
# 也可以将值放到列表中
def foo(x):
    return x+1
foo1 = foo(10)

def inc(x):
    return x[0]+1
foo1 = [10]
print(inc(foo1))
print()


# 4.2 关键字参数和默认值
# 关键参数
# 当参数比较多时,可以使用名称来指定参数,这种参数称为关键字参数
def hello_1(greeting, name):
    print('{},{}!'.format(greeting,name))
hello_1('Hello','World')

hello_1(greeting='Hello', name='World')
print()

# 关键参数可以指定默认值
# 给定默认值后,调用函数,可以不提供参数或提供部分参数
def hello_2(greeting = 'Hello', name = 'World'):
    print('{},{}'.format(greeting,name))

hello_2()
hello_2('Greeting')
hello_2(name='Tana')

# 也可以位置参数和关键参数一起使用
# 一般而言,除非必不可少的参数很少,而带默认参数值的可选参数很多,否则不应结合使用关键字参数和位置参数
def hello_3(name, greeting = 'Hello', puctuation = ''):
    print('{},{}{}'.format(greeting, name, puctuation))
hello_3('Tana')


# 4.3 收集参数
# *param 将会收集余下的位置参数,并将它们放到一个元组中
# 如果没有可供收集的参数,param将会是一个空元组
def print_params(*param):
    print(param)
print_params(1, 2, 3, 4)
print()

def print_params2(title, *params):
    print(title,params)
print_params2('Params:' , '1', '2', '3')
print()

# 与赋值时一样,带星号*参数也可放到其他位置(而不是最后),但不同的是,
# 这种情况下需要使用名称来指定后续参数
def in_the_middle(x, *y, z):
    print(x, y, z)
in_the_middle(1, 2, 3, 4, 5, 6, z=7)
print()

# 要收集关键字参数,可使用两个星号
# 这样得到的参数 是一个字典 而不是一个元组
def print_params3(**param):
    print(param)
print_params3(x=1, y=2, z=3)
print()

def print_params4(x, y, z=3, *pospar, **keypar):
    print(x, y, z)
    print(pospar)
    print(keypar)
print_params4(1, 2, 3, 4, 5, 6, 7,foo1=1, foo2=2)
print()
print_params4(1, 2, 4, 5, 6, 7, foo1=1, foo2=2)
print()
print_params4(1, 2)
print()


# 4.4 分配参数
# 与收集参数相反 对参数加星号*或**
# 元组参数需分配用*
# 字典参数需分配用**
def add_1(x, y):
    print(x+y)
param = (1, 2)
add_1(*param)
print()

def hello_4(name, greeting = 'Hello', puctuation = '!'):
    print('{},{}{}'.format(greeting, name, puctuation))
param = {'name': 'Tana','greeting':'Well met'}
hello_4(**param)
print()

# 只有在定义函数(允许可变数量的参数)或调用函数时(拆分字典或序列)使用,星号才能发挥作用
# * 原参数是元组或字典,*param或**param 就会分配参数  原参数是多个参数 *param或**param就会收集参数
# 定义函数 带*代表收集参数
# 调用函数 带*代表分配参数
def with_stars(**kwds):
    print(kwds['name'],kwds['age'])
def without_stars(kwds):
    print(kwds['name'], kwds['age'])

args = {'name':'Tana', 'age':24}
with_stars(**args)
without_stars(args)
print()

# 练习使用参数
def story(** kwds):
    print('{job} {name}'.format_map(kwds))
def power(x, y, *other):
    print('other:',other)
    print(pow(x,y))

story(job='Python', name='Tana')
print()

param = {'job':'Pathon', 'name':'Zere'}
story(**param)
print()

power(2, 3, 4)
print()

power(2, 3, 5, 6)
print()

power(3, 4, 'Hello World')
print()

power(3, *range(3,10))
print()

power(*range(3, 10))
print()


#########################################################################
# 5 作用域 命名空间
# 每次调用函数都会创建一个新的命名空间,供函数内部调用
# 在函数内部使用的变量称为局部变量 在函数外部的称为全局变量  慎用全局变量
# 如果一个局部变量或参数与你要访问的全局变量名相同,在函数内部就无法直接访问这个全局变量
# 因为它会被局部变量遮住 可以使用globals()['parameter']来访问全局变量

# 作用域嵌套
# 在函数中返回函数
# 一个函数位于另一个函数中,且外面的函数返回里面的函数。也就是返回一个函数,而不是调用它。
# 重要的是,返回的函数能够访问外部函数定义的作用域,换而言之,它携带着自己所在的作用域(相关的变量)
def multiplier(factor):
    def multiplyByFactor(number):
        return number *factor
    return multiplyByFactor

double = multiplier(2)
print(double(4))
print()

print(multiplier(5)(4))
print()

# 像multiplyByFactor这样存储其所在作用域的函数称为闭包
# 通常,不能给外部作用域内的变量赋值,但如果一定要这样做,可以使用关键字nonlocal
# 这个关键字的用法与glogal很像,让你能够给外部作用域(非全局作用域)内的变量赋值


#########################################################################
# 6. 递归
# 递归要素
# 1.基线条件(针对最小问题):满足这种条件时,函数将直接返回一个值
# 2.递归条件:包含一个或多个调用,这些调用旨在解决问题的一部分

# 阶乘
def factorial(n):
    if n==1:
        return 1
    else:
        return n*factorial(n-1)

print(factorial(4))
print()

# 幂
def power(x, y):
    if y==0:
        return 1
    else:
        return x*power(x, y-1)

print(power(2, 4))
print()

# 二分查找
def search(seq, num, lower=0, upper=None):
    if upper==None: upper=len(seq)-1
    if lower==upper:
        assert num == seq[upper]
        return upper
    else:
        middle = (lower + upper)//2
        if num > seq[middle]:
           return search(seq, num, middle+1, upper)
        else:
           return search(seq, num, lower, middle-1)

seq = [34, 67, 8, 123, 4, 100, 96]
seq.sort()
print(seq)
print(search(seq, 34))
print()

# map函数
a = list(map(str, range(10)))
print(a)

# filter函数 过滤
# filter根据布尔函数的返回值对元素进行过滤
def func(x):
    return x.isalnum()
seq = ['foo','42','?!',"******"]
print(list(filter(func, seq)))
print()

# lambda 表达式 能够创建内嵌的简单函数(主要供map filter reduce使用)
# reduce函数 使用指定的函数将序列前两个元素合二为一,再将结果和第3个元素合二为一,
# 以此类推,直到处理完整个序列并得到一个结果

# 将序列里的所有数相加
numbers = [73, 56, 67, 87, 90, 12, 14, 34, 56]
from functools import reduce
a = reduce(lambda x, y : x+y, numbers)
print(a)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,576评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,515评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,017评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,626评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,625评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,255评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,825评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,729评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,271评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,363评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,498评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,183评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,867评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,338评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,458评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,906评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,507评论 2 359

推荐阅读更多精彩内容