前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python函数

Python函数

作者头像
Python技术与生活认知的分享
发布2018-07-03 12:17:21
9890
发布2018-07-03 12:17:21
举报
文章被收录于专栏:AzMark

阅读文本大概需要 6 分钟

写在前面

这段时间通过公号写文章结交了许多志同道合的朋友,他们中有和我一样的大学生、研究生、以及已经工作的前辈。虽然处于不同的人生阶段,但彼此聊得很 High ,每个人的成长历程中总有相似的地方,遇到的困惑迷茫也大致相同。通过相互间的交流沟通,可能困扰自己很久的问题于前辈而言只是一个小 Case ,所以说要勤于沟通,去找寻属于自己的圈子,这样你才能提升得更快。

分享给大家一个观点,提升认知优先于积累知识。我的微信个签是「努力固然重要,但请记得选择比努力更重要」因为你做出选择的前提是你必须具备一定的认知,方向都错了,努力又有什么用呢,不过是南辕北辙,希望给大家带来一些思考。

Python

01

代码块与笔记

函数

参数传递1

代码语言:javascript
复制
"""

参数传递包含:可更改(mutable)与不可更改(immutable)对象

在 Python 中,string tuple number 是不可更改的对象,而 list dict 等则是可以修改的对象

Python 中一切都是对象,严格意义上,我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象

"""


s = "Mark"

l = [1, 2, 3]


"""

在 Python 中,类型属于对象,变量是没有类型的:

以上代码中: " Mark " 是 String 类型,[1,2,3] 是 list 类型,而变量 l 与 s 是没有类型的,

仅仅是一个对象的引用(一个指针),可以是指向 list 类型对象,也可以是指向 string 类型对象

"""

“值”传递2

代码语言:javascript
复制
# 值传递:传递不可变类型 string tuple number 是不可变的

num = 20

num = 10

print(num)  # 10


"""

不可变类型:变量赋值 num = 20 后再赋值 num = 10,这里实际上是生成

一个新的 int 值对象 10,再让 num 指向它,而 旧对象 20 被当成垃圾处理了

类似 C++ 的值传递,如整数、字符串、元组。fun(num),传递的只是 num 的值,没有影响

num 对象本身。在 fun(num)内部修改 num 的值,只是修改另一个复制的对象,并不会影响 num 本身

"""


def f1(num):

    num = 10

    print(num)  # 10

num = 20

f1(num)

print(num)  # 20

“引用”传递3

代码语言:javascript
复制
# 引用传递:传递可变类型 list,dict 是可变的


"""

可变类型:变量赋值 l = [1, 2, 3] 后再赋值 l[2] = 4 则是将 l 的

第三个元素值更改,本身 l 没有动,只是其内部的一部分值被修改了

类似 C++ 的引用传递,如 列表,字典。fun(l)是

将 l 真正的传过去,修改后 fun 外部的 l也会受影响

"""


def f2(l):

    l[0] = 0

    print(l)  # [0, 2, 3, 4, 5]

l = [1, 2, 3, 4, 5]

f2(l)

print(l)  # [0, 2, 3, 4, 5]

匿名函数4

代码语言:javascript
复制
"""

Python 使用 lambda 来创建匿名函数

1.lambda 只是一个表达式,函数体比 def 简单很多

2.lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去

3.lambda 函数拥有自己的命名空间,且不能访问作用域外的其他变量

"""


_sum = lambda num1, num2: num1 + num2 

print(_sum(1, 2))  # 3

递归函数5

代码语言:javascript
复制
"""

递归调用:一个函数,调用了自身,称为递归调用

递归函数:一个会调用自身的函数称为递归函数

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰

凡是循环能干的,递归都能干

"""


def _sum(n):

    if n == 1:

        return 1

    return n + _sum(n-1)

_sum = _sum(4)  # 10

print(_sum)


"""

递归函数的缺点是使用递归函数需要注意防止栈溢出

在计算机中,函数调用是通过栈(stack)这种数据结构实现的

每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧

由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出

如果不信的话大家可以把上面的 n 改得大一点

"""

迭代6.1

代码语言:javascript
复制
"""

如果给定一个 list 或 tuple ,我们可以通过 for 循环来遍历这个 list 或tuple ,

这种遍历我们称为迭代(Iteration)

在 Python 中,迭代是通过 for ... in 来完成的

可迭代对象(Iterable):可以直接作用于 for 循环的对象,无论有无下标

可以直接作用于 for 的数据类型一般分为两种:

1.集合数据类型:如list tuple dict set string

2.是 generator,包括生成器和带 yield 的 generator function

"""


l = [1, 2, 3]

for i in l:

    print(i)

d = {"Iu": 26, "Mark": 18}

for k, v in d.items():

    print(k, v)

迭代6.2

代码语言:javascript
复制
# 从 collections 模块导入

from collections import Iterable


"""

如何判断一个对象是可迭代对象呢?方法是通过 collections 模块中的 

Iterable 类型判断:isinstance()去判断一个对象是否是Iterable对象

"""


print(isinstance([], Iterable))  # T

print(isinstance((), Iterable))  # T

print(isinstance({}, Iterable))  # T

print(isinstance("", Iterable))  # T

# 生成器 generator

print(isinstance((x for x in range(10)), Iterable))  # T

print(isinstance(1, Iterable))   # F


"""

如果要对 list 实现下标循环(同时输出索引与值)怎么办?

Python 内置的 enumerate 枚举函数可以把一个 list 变成索引-元素对,

这样就可以在for循环中同时迭代索引和元素本身

"""


# 同时引用两个变量

l = [(1, 2), (3, 4), (4, 5)]

for x, y in l:

    print(x, y)


l = [1, 2, 3]

for i, v in enumerate(l):

    print(i, v)

列表生成式7

代码语言:javascript
复制
# 导入 os 模块

import os


# 列表生成式是 Python 内置的非常简单强大的用来创建 list 的

l = [x * x for x in range(1, 5)]

print(l)  # [1, 4, 9, 16]


# 加上if判断,筛选出偶数的平方

l = [x * x for x in range(1, 5) if x % 2 == 0]

print(l)  # [4, 16]


# 还可以使用两层循环,可以生成全排列:

c = [m + n for m in 'AB' for n in 'XY']

print(c)  # ['AX', 'AY', 'BX', 'BY']


# os.listdir可以列出文件和目录

l = [d for d in os.listdir('.')]

print(l)

生成器 generator8.1

代码语言:javascript
复制
"""

通过列表生成式一次性直接创建的列表既受到内存的限制,也会造成资源的浪费

为节省空间,不必创建完整的list,采用一边循环一边计算的机制,称为生成器:generator

"""


# 1.列表生成式改成generator

# 创建 l 和 g 的区别仅在于最外层的[]和()

g = (x * x for x in range(4))

# <generator object <genexpr> at 0x000002077826CFC0>

print(g)


# 遍历 g 元素

for i in g:

    print(i)

生成器 generator8.2

代码语言:javascript
复制
# 2.函数定义中包含 yield 关键字,这个函数就不再是一个普通函数,而是一个generator


"""

斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, ...

"""


def fib(x):

    n, a, b = 0, 0, 1

    while n < x:

        # 1    1   2   3   5

        print(b, end="\t")

        a, b = b, a + b

        n += 1

    print("")

fib(5)


"""

fib 函数中斐波拉契数列的推算规则,从第一个元素开始,推算出后续元素,逻辑类似于generator

要把fib函数变成 generator,只需把 print(b)改为yield b 即可:

"""


def fib(x):

    n, a, b = 0, 0, 1

    while n < x:

        yield b

        a, b = b, a + b

        n += 1

f = fib(5)

# 注意普通函数返回结果,generator 函数返回一个 generator 对象

# <generator object fib at 0x000002C1944C7EB8>

print(f)


"""

generator和函数的执行流程不同。函数是顺序执行,遇到return语句

或者最后一行函数语句返回;而变成 generator 的函数,在每次调用next()的时候执行,

遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

"""

def f():

    print('step 1')

    yield 1

    print('step 2')

    yield(2)

# 调用该generator时,先生成一个generator对象,再用next()函数不断获得下一个返回值

f = f()

# 注意:越界会出现 StopIteration 错误

next(f)  # step 1

02

练习

如果您是刚开始学习 Python 不久,个人感觉今天的分享还是有难度的,大家多花点时间消化一下。函数的知识还有一些,怕大家一次性消化不了,所以今天就分享到这。后天我们继续函数与模块的学习,大家一起加油!

写在最后

最后给大家推送波福利!!!如果你打算入手或着正在学习Python,欢迎加入我们一起学习。后台回复「Python」,获取到你想要的资源。同时我们组建了一个Python技术学习群,里面大佬与小白都有,有很好的学习氛围。想要进群学习的,加 Mark 微信「IMark950831」,备注「加群」,期待你的到来!

好了,今天的分享就到这了,觉得写得不错的,点赞转发支持下。

推荐阅读:

Python函数的介绍

给我一首歌的时间

原创不易,感谢分享

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-05-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python梦工厂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档