master
/ 4.4 匿名函数.ipynb

4.4 匿名函数.ipynb @master

341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d487d71
341084b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4.5 匿名函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color=Red>__匿名函数__</font>即是一个没有函数名字的<font color=Red>__临时使用__</font>的小函数,在Python中使用<font color=Red>__lambda__</font>表达式创建匿名函数。\n",
    "lambda表达式只能包含一个表达式,不允许包含选择、循环等语法结构,其语法如下:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lambda 参数列表 : 表达式(或条件表达式)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "相当于函数定义:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def fun(参数列表):    #参数可以是一个,也可以是多个\n",
    "    return 表达式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python提供了很多<font color=Red>__函数式编程__</font>的特性,如soretd(),map(),reduce(),filter()等,这些函数都支持以函数作为参数。lambda函数可以应用在函数式编程里。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表['58','01','9','920']元素的排序可以使用sorted()函数,sorted()语法如下:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sorted(iterable, * , key = None, reverse = False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "其中key参数可以接收函数,以函数的返回值作为排序依据。reverse = False 表示默认升序排列,可以用 reverse = True 来指定降序排列。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lambda x: len(x)\n",
    "\n",
    "\n",
    "ls = ['58', '01', '9', '920']            # 定义列表\n",
    "print(sorted(ls))                        # 对列表里的元素直接排序,即字符串的大小比较排序,默认升序\n",
    "print(sorted(ls, key=int))               # 指定排序依据为int()函数,即将列表元素转换为整型后比较大小,升序排列\n",
    "print(sorted(ls, key=f))                 # 指定排序依据为f()函数,即列表元素的串长做排序依据,升序排列"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面的f()函数功能很简单,而且只是临时需要,可以使用lambda函数来代替。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ls = ['58', '01', '9', '920']            # 定义列表\n",
    "print(sorted(ls, key=lambda x : len(x))) # 指定排序依据为lambda()函数,求列表元素的串长,以其做排序依据,升序排列"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font face='楷体' color='red' size=5> 练一练 </font>\n",
    "\n",
    "现有列表ls = [3,8,-3,-1,0,-2,-9],请(1)将列表ls中的元素按升序排序输出;(2)再按照<font color=Red>__绝对值__</font>的大小进行<font color=Red>__降序__</font>排序输出。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#提示1:reverse = True 来指定降序排列\n",
    "#提示2:key = lambda x: abs(x)  来指定排序依据为列表各元素的绝对值\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  用一行代码实现判断素数的函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "is_prime = lambda x: all(map(lambda f: x % f, range(2, int(x ** 0.5) + 1)))\n",
    "\n",
    "print(is_prime(37))  # True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "all函数也是 Python 内置函数,如果传入的序列中所有的布尔值都是True,all函数返回True,否则all函数返回False。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 用一条语句输出不超过100的所有素数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(*filter(lambda x: all(map(lambda f: x % f, range(2, int(x ** 0.5) + 1))), range(2, 101)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 分两条语句"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "is_prime = lambda x: all(map(lambda f: x % f, range(2, int(x ** 0.5) + 1)))\n",
    "print(*filter(is_prime, range(2, 101)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "lambda函数拥有自己的命名空间,<font color=Red>__不能访问__</font>自有参数列表之外或全局命名空间的参数。\n",
    "\n",
    "lambda表达式<font color=Red>__不需要return__</font>来返回值,表达式本身的计算结果就是函数的返回值。\n",
    "\n",
    "lambda主体是一个表达式,而不是代码块,仅能在表达式中封装有限的逻辑,<font color=Red>__不允许包含其它复杂的语句__</font>,最多只能使用类似条件表达式这样的三元运算。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color=Red>__filter()函数__</font>用于过滤序列,过滤掉不符合条件的元素,返回符合条件的元素构成的序列。filter()接收一个函数和一个序列,将函数依次作用于每个元素,然后根据返回的布尔值决定保留还是丢弃该元素。\n",
    "\n",
    "filter()函数返回的是一个生成器,也是一个惰性序列,可以用 * 来<font color=Red>__解包__</font>,也可以使用list()函数将其转换为列表。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面的代码使用filter()和lambda(),用一行代码找出了100以内与3相关的自然数。\n",
    "\n",
    "所谓与3相关的数是指能被3整除或数字里包含“3”的数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print( * filter(lambda x: x%3 == 0 or x%10 == 3 or x//10 == 3, range(101)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在Python中,可以将一些逻辑拿到函数外面,定义一个裁减过的 lambda 函数以实现目标功能。这种方式更为高效优雅,而且可以减少异常错误。\n",
    "\n",
    "lambda的使用可<font color=Red>__简化代码__</font>,使代码简洁清晰。不过,这种方法会在一定程度上<font color=Red>__降低代码的可读性__</font>。\n",
    "\n",
    "关于lambda在使用在Python社区也存在争议,Python程序员对于到底要不要使用lambda意见不一致。支持者认为使用lambda编写的代码更紧凑,更<font color=Red>__“pythonic”__</font>。反对方认为,lambda函数能够支持的功能十分有限,不支持多分支程序和异常处理程序;而且,lambda函数的功能被隐藏,对于编写代码之外的人员来说,理解lambda代码需要耗费一定的时间成本。\n",
    "在实际中,是否使用lambda取决于程序员的个人喜好。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}