一览函数式编程

news2025/1/12 12:05:41

文章目录

    • 一、 什么是函数式编程
      • 1.1 编程范式
        • 1.1.1 命令式编程(Imperative Programming)范式
        • 1.1.2 声明式编程(Declarative Programming)范式
        • 1.1.3 函数式编程(Functional Programming)范式
        • 1.1.4 面向对象编程(Object-Oriented Programming)范式
        • 1.1.5 元编程(Metaprogramming)范式
      • 1.2 数学函数
      • 1.3 函数是一等公民(Functions are first-class citizens)
        • 1.3.1 函数可以被赋值给变量或者数据结构中的元素
        • 1.3.2 函数可以作为参数传递给其他函数
        • 1.3.3 函数可以作为其他函数的返回值
        • 1.3.4 函数可以在运行时动态创建和定义
      • 1.4 不可变性(immutability)和无副作用
    • 二、函数式编程的基础
      • 2.1 纯函数(pure function)
      • 2.2 闭包(closure)
      • 2.3 Lambda
      • 2.4 高阶函数
      • 2.5 偏函数(Partial)
      • 2.6 柯里化(Currying)
        • 柯里化转换
        • 优势
    • 三、函数式编程的进阶
      • 3.1 函数组合(composition)
      • 3.2 Pipeline
      • 3.3 PointFree
      • 3.4 惰性求值(Lazy evaluation)
      • 3.5 尾递归(Tail recursion)
      • 3.6 MapReduce
        • 3.6.1 多线程
    • 四、总结
      • 4.1 优缺点
        • 4.1.1 优点
        • 4.1.2 缺点

一、 什么是函数式编程

函数式编程是一种编程范式,它将计算视为数学函数的求值过程。在函数式编程中,函数是一等公民,可以像其他值一样被传递、组合和操作。函数式编程强调不可变性和无副作用,即函数的执行不会改变程序状态或外部环境。这使得函数式编程更容易进行推理和测试,并且可以更好地支持并发和并行计算。

1.1 编程范式

编程范式是一种编程思想或方法,它定义了如何组织和结构化计算机程序。不同的编程范式有不同的方法和规则,以解决不同类型的问题。
同一门语言,同一个问题,来看一下不同的范式,会写出什么样的代码

问题:计算一个整数数组中所有元素的平均值。

1.1.1 命令式编程(Imperative Programming)范式

命令式编程范式是一种基于语句的编程范式,它通过一系列指令来改变程序状态。在命令式编程中,程序员需要指定每个步骤的操作,以便计算出所需的结果。

img

1.1.2 声明式编程(Declarative Programming)范式

声明式编程范式是一种基于表达式的编程范式,它通过表达式来描述计算机程序的行为。在声明式编程中,程序员只需要描述所需的结果,而不需要指定每个步骤的操作。

img

1.1.3 函数式编程(Functional Programming)范式

函数式编程范式是一种基于函数的编程范式,它将计算机程序视为一系列函数的组合。在函数式编程中,程序员只需要定义函数的输入和输出,而不需要指定每个步骤的操作。

img

1.1.4 面向对象编程(Object-Oriented Programming)范式

面向对象编程范式是一种基于对象的编程范式,它将计算机程序视为一组相互作用的对象。在面向对象编程中,程序员定义对象的属性和方法,并使用这些对象来执行计算机程序的操作。

img

1.1.5 元编程(Metaprogramming)范式

元编程范式是一种编程范式,它允许程序员在运行时创建、修改和操作程序的结构和行为。元编程范式的目的是使程序更加灵活和可扩展,因为它允许程序在运行时自我修改和适应。

img

1.2 数学函数

假设有一个数学函数 f(x) = x^2,它将一个数 x 映射到它的平方。在函数式编程中,我们可以定义一个函数 square(x),它也将一个数 x 映射到它的平方。这个函数可以用如下的方式定义:

img

这个函数与数学中的函数 f(x) = x^2 有很多相似之处。它们都将一个输入映射到一个输出,而且输出只取决于输入,不会受到外部状态的影响。在函数式编程中,我们也可以将这个函数作为另一个函数的参数,或者将它的输出作为另一个函数的输入,这也是函数式编程中常见的操作。

另外,函数式编程中的函数也具有不可变性和纯函数性质。这意味着函数的输出只取决于输入,不会受到外部状态的影响。例如,如果我们调用 square(2) 函数,它的输出始终为 4,不会受到任何外部状态的影响。这与数学中的函数也有很多相似之处,因为数学中的函数的输出也只取决于输入,不会受到外部环境的影响。

1.3 函数是一等公民(Functions are first-class citizens)

是指在编程语言中,函数可以像其他数据类型一样被传递、赋值、作为参数和返回值使用。
具体来说,函数作为一等公民具有以下特点:

1.3.1 函数可以被赋值给变量或者数据结构中的元素

img

1.3.2 函数可以作为参数传递给其他函数

img

1.3.3 函数可以作为其他函数的返回值

img

1.3.4 函数可以在运行时动态创建和定义

img

1.4 不可变性(immutability)和无副作用

不可变性是指在程序执行过程中,某个对象的状态不会发生改变。在函数式编程中,不可变性是一个重要的概念,因为它可以避免副作用和竞态条件等问题。在不可变性的约束下,函数的执行结果只取决于输入参数,而不会受到外部环境的影响。这使得函数更容易进行推理和测试,并且可以更好地支持并发和并行计算。在实现不可变性时,可以使用一些技术,例如使用不可变数据结构、避免共享可变状态、使用纯函数等。

img

反之

img

带来的问题

  1. 副作用:在使用可变性的情况下,我们直接修改了sum_of_numbers变量的值,这可能会导致副作用。副作用是指函数或程序对外部环境产生的影响,例如修改全局变量、打印输出等。副作用可能会使程序更难以理解和调试,因为它们使程序的行为不可预测。
  2. 竞态条件:如果在计算平均值的过程中,有其他线程或进程也在修改sum_of_numbers变量的值,那么可能会导致计算结果不正确。竞态条件是指多个线程或进程同时访问共享资源时,由于访问顺序不确定,导致程序的行为不可预测。
  3. 可读性和可维护性:如果我们在程序的其他地方也使用了sum_of_numbers变量,那么可能会导致代码的可读性和可维护性下降。因为我们不知道sum_of_numbers变量的值是在哪里修改的,也不知道它的值是否正确。

因此,使用可变性来计算平均值可能会带来一些问题。相比之下,使用不可变性可以避免这些问题,使程序更容易理解和调试。

二、函数式编程的基础

2.1 纯函数(pure function)

纯函数是指在相同的输入下,总是返回相同的输出,并且没有任何副作用的函数。具体来说,纯函数满足以下两个条件:

  1. 相同的输入总是返回相同的输出。
  2. 函数执行过程中没有对外部环境产生任何影响,也就是没有副作用。

纯函数的好处在于它们更容易进行测试和调试,因为它们的行为是可预测的。此外,纯函数还可以更容易地进行并行化和优化,因为它们不依赖于外部状态。
例如,下面是一个纯函数的例子:

img

这个函数总是返回相同的输出,而且没有任何副作用。无论何时调用它,它都只是简单地将两个数字相加并返回结果。

Question:这是一个纯函数吗?

img

2.2 闭包(closure)

闭包是指一个函数和它所引用的外部变量的组合。在函数式编程中,闭包通常用于创建高阶函数,这些函数可以接受其他函数作为参数或返回函数作为结果。
闭包可以捕获外部变量的状态,并在函数调用之间保留它。这使得闭包可以实现一些有趣的功能,如记忆化和延迟计算。
例如,以下代码创建了一个闭包,它返回一个函数,该函数可以访问外部变量x:

img

在这个例子中,createAdder函数返回一个函数,该函数可以访问外部变量x。我们可以使用createAdder(5)创建一个新的函数add5,它将5添加到它的参数中。由于add5是一个闭包,它可以记住x的值,并在每次调用时使用它。

2.3 Lambda

Lambda是一种匿名函数,它可以在需要时被创建和调用,而不需要给它们命名。在JavaScript中,Lambda函数可以使用箭头函数语法来定义。

img

2.4 高阶函数

高阶函数是指能够接收一个或多个函数作为参数,并且/或者返回一个新函数的函数。函数是一等公民,因此函数可以像其他值一样被传递和操作。高阶函数是利用这种特性来实现更加灵活和抽象的编程方式。
以下是一些JavaScript中的高阶函数示例:

  1. **Array.prototype.map():**接收一个函数作为参数,该函数将应用于数组中的每个元素,并返回一个新数组,其中包含每个元素应用该函数的结果。

img

  1. **Array.prototype.filter():**接收一个函数作为参数,该函数将应用于数组中的每个元素,并返回一个新数组,其中包含满足该函数条件的元素。

    img

  2. **Array.prototype.reduce():**接收一个函数作为参数,该函数将应用于数组中的每个元素,并返回一个累加器的值。

    img

  3. 使用多个函数作为参数

img

2.5 偏函数(Partial)

偏函数是指将一个多参数函数转化为一个只有部分参数的函数,即固定函数的一些参数,使得这个新函数只需要传入剩余的参数即可完成调用。这样做的好处是可以简化函数的调用,减少重复代码的编写,提高代码的可读性和可维护性。

img

2.6 柯里化(Currying)

柯里化是一种函数式编程技术,它将一个接受多个参数的函数转换为一系列只接受单个参数的函数。这些单参数函数可以被组合在一起,以便在后续的计算中使用。
例如,假设有一个接受两个参数的函数 add(x, y),我们可以使用柯里化将其转换为一系列只接受一个参数的函数:

img

现在,我们可以使用这些单参数函数来进行计算:

img

这里,我们首先使用 add(1) 创建了一个新的函数 add_1,它只接受一个参数 y,并将其与 1 相加。然后,我们使用 add(2) 创建了另一个新的函数 add_2,它也只接受一个参数 y,并将其与 2 相加。最后,我们使用这些新函数来计算 add_1(3) 和 add_2(3),得到了正确的结果。
柯里化可以使代码更加简洁和可读,同时也可以提高代码的复用性和灵活性。

柯里化转换

下面是一个使用 JavaScript 实现柯里化的函数:

img

这个函数接受一个函数 fn 作为参数,并返回一个新的函数 curried,这个新函数可以接受任意数量的参数,并将它们逐步累积起来,直到收集到足够的参数后再调用原始函数 fn。
具体来说,当 curried 函数接收到的参数数量大于或等于 fn 函数的参数数量时,它会直接调用 fn 函数,并将收集到的参数传递给它。否则,它会返回一个新的函数,这个新函数可以接受更多的参数,并将它们与之前收集到的参数合并起来,然后递归调用 curried 函数,直到收集到足够的参数后再调用 fn 函数。
下面是一个使用 curry 函数实现柯里化的例子:

img

在这个例子中,我们定义了一个接受三个参数的函数 add(x, y, z),然后使用 curry 函数将它转换为一个柯里化函数 curriedAdd。最后,我们使用 curriedAdd 函数来计算 add(1, 2, 3),add(1, 2, 3),add(1, 2, 3) 和 add(1, 2, 3),得到了正确的结果。

优势
  1. 延迟执行:柯里化可以将一个函数的执行延迟到后续的计算中,这样可以避免不必要的计算和资源浪费。例如,在上面的例子中,我们可以先使用 add(1) 和 add(2) 创建两个新函数,然后在需要计算时再传递参数,这样可以避免重复计算和资源浪费。

  2. 函数组合:柯里化可以将多个函数组合在一起,以便在后续的计算中使用。例如,我们可以将多个只接受单个参数的函数组合在一起,形成一个新的函数,这个新函数可以接受多个参数,并将它们依次传递给这些单参数函数,从而得到最终的结果。

    img

柯里化是将一个接受多个参数的函数转换为一系列只接受单个参数的函数,这些单参数函数可以被组合在一起,以便在后续的计算中使用。柯里化的目的是为了提高代码的复用性和灵活性,使得代码更加简洁、可读和灵活。
偏函数是将一个接受多个参数的函数转换为一个接受部分参数的函数,这个部分参数是在转换时就已经确定的。偏函数的目的是为了简化函数调用,避免重复传递相同的参数,提高代码的可读性和可维护性。

三、函数式编程的进阶

3.1 函数组合(composition)

函数组合是一种将多个函数组合在一起以形成新函数的技术,可以帮助我们更好地组织和重用代码。
在函数组合中,我们将一个函数的输出作为另一个函数的输入,以此类推,直到我们得到最终的输出。这种方法可以让我们将多个简单的函数组合成一个更复杂的函数,从而使代码更加模块化和可读性更高。
例如,假设我们有两个函数 f(x) 和 g(x),我们可以将它们组合成一个新函数 h(x) = f(g(x))。这个新函数 h(x) 将先应用 g(x),然后将其结果传递给 f(x)。
函数组合还可以用于构建管道,其中每个函数都是前一个函数的输出。这种方法可以让我们轻松地将多个函数链接在一起,以便在数据流中进行转换和处理。

img

3.2 Pipeline

pipeline 是一种将多个函数组合在一起,形成一个数据处理流程的编程模式。它的核心思想是将数据从一个函数传递到另一个函数,每个函数都对数据进行一些操作,最终得到最终结果。
在函数式编程 pipeline 中,通常会使用一些高阶函数,如 map、filter、reduce 等,来对数据进行处理。这些函数可以接受一个函数作为参数,并将其应用于数据中的每个元素。
下面是一个简单的函数式编程 pipeline 的示例:

img

3.3 PointFree

函数式编程中的 pointfree 是一种编程风格,它的核心思想是尽可能地避免使用命名参数,而是通过组合函数来实现代码的复用和简化。
在 pointfree 风格中,函数的定义不会显式地引用它的参数,而是通过组合其他函数来实现其功能。这种风格的优点在于可以使代码更加简洁、可读性更高,并且可以更容易地进行代码重构和测试。

JavaScript

img

Scala

img

Go

img

3.4 惰性求值(Lazy evaluation)

惰性求值是一种计算策略,它只在需要时才计算表达式的值。这意味着,如果一个表达式的值从未被使用,那么它将永远不会被计算。相反,它只有在需要时才会被计算,这可以节省计算资源和提高程序的效率。
在函数式编程语言中,函数可以作为参数传递给其他函数,也可以从其他函数中返回。惰性求值可以使这些函数更加灵活和高效。只在需要时才计算表达式的值,可以提高程序的效率和灵活性。

img

在这个例子中,lazyAdd 函数返回一个函数,这个函数会在需要时才计算 a + b 的值。当我们调用 lazyAdd(2, 3) 时,它并不会立即计算 2 + 3 的值,而是返回一个函数。当我们调用这个函数时,它才会计算 2 + 3 的值并返回。
这种方式可以避免不必要的计算,提高程序的效率。例如,如果我们有一个很大的数组,我们可以使用惰性求值来避免不必要的遍历:

img

在这个例子中,lazyFilter 函数返回一个生成器函数,这个函数会在需要时才遍历数组并返回符合条件的元素。当我们调用 lazyFilter(arr, x => x % 2 === 0) 时,它并不会立即遍历数组,而是返回一个生成器函数。当我们使用 for…of 循环遍历这个生成器函数时,它才会遍历数组并返回符合条件的元素。这种方式可以避免不必要的遍历,提高程序的效率。

3.5 尾递归(Tail recursion)

递归

img

在这个实现中,递归调用发生在函数的中间,每次递归调用都需要等待下一层递归的返回值才能继续执行。这种形式的递归可能会导致栈溢出等问题,因为每次递归调用都会在栈中创建一个新的帧,如果递归层数太多,就会导致栈溢出。
尾递归
指一个函数在调用自身之后,不再有其他操作需要执行,直接返回结果。这种形式的递归可以被优化为迭代,从而避免栈溢出等问题。
在尾递归中,递归调用发生在函数的最后一步,而且递归调用的返回值直接被当前函数返回,不再进行其他操作。这种形式的递归可以被编译器或解释器优化为迭代,从而避免栈溢出等问题。
例如,下面是一个阶乘函数的尾递归实现:

img

在这个实现中,递归调用发生在函数的最后一步,而且递归调用的返回值直接被当前函数返回,不再进行其他操作。这种形式的递归可以被优化为迭代,从而避免栈溢出等问题。

3.6 MapReduce

在函数式编程中,Map和Reduce是两个常用的高阶函数。Map函数接受一个函数和一个列表作为输入,将该函数应用于列表中的每个元素,并返回一个新的列表。Reduce函数接受一个函数和一个列表作为输入,将该函数应用于列表中的每个元素,并返回一个单一的值。
在MapReduce中,Map函数将数据集分成小块,并将每个块映射到一个键值对。Reduce函数将相同键的所有值组合在一起,并将它们合并成一个单一的值。这个过程可以在分布式计算环境中并行执行,从而加快处理速度。

img

3.6.1 多线程

img

四、总结

4.1 优缺点

4.1.1 优点
  1. 简洁性:函数式编程通常比命令式编程更简洁,因为它们不需要维护状态或副作用。这使得代码更容易理解和维护。
  2. 可读性:函数式编程通常更容易阅读,因为它们的代码更加模块化和组合化。这使得代码更容易理解和修改。
  3. 可扩展性:函数式编程通常更容易扩展,因为它们的代码更加模块化和组合化。这使得代码更容易重用和修改。
  4. 可靠性:函数式编程通常更可靠,因为它们不依赖于共享状态或副作用。这使得代码更容易测试和调试。
  5. 并行性:函数式编程通常更容易并行化,因为它们的代码不依赖于共享状态或副作用。这使得代码更容易利用多核处理器和分布式系统。
4.1.2 缺点
  1. 性能:函数式编程通常比命令式编程更慢,因为它们需要更多的内存和计算资源来处理数据。这使得函数式编程不适合处理大规模数据或高性能应用程序。
  2. 学习曲线:函数式编程通常比命令式编程更难学习,因为它们需要更多的数学和抽象思维。这使得函数式编程不适合初学者或非技术人员。
  3. 可读性:函数式编程通常比命令式编程更难阅读,因为它们的代码更加抽象和符号化。这使得函数式编程不适合所有人,特别是那些不熟悉函数式编程的人。
  4. 可维护性:函数式编程通常比命令式编程更难维护,因为它们的代码更加抽象和符号化。这使得函数式编程不适合所有人,特别是那些不熟悉函数式编程的人。
  5. 工具支持:函数式编程通常比命令式编程缺乏工具支持,因为它们需要更多的数学和抽象思维。这使得函数式编程不适合所有人,特别是那些需要使用工具来提高生产力的人。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1650827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pascal Content数据集

如果您想使用Pascal Context数据集,请安装Detail,然后运行以下命令将注释转换为正确的格式。 1.安装Detail 进入项目终端 #即 这是在我自己的项目下直接进行克隆操作: git clone https://github.com/zhanghang1989/detail-api.git $PASCAL…

我用 GitHub 9.8k 的 Go 语言 2D 游戏引擎写了个游戏

前言 hi,大家好,这里是白泽。今天给大家分享一个 GitHub 🌟9.8k 的 Go 语言 2D 游戏引擎。 https://github.com/hajimehoshi/ebiten 引擎的贡献者依旧在积极维护,是一个兼具学习 & 娱乐的项目! 为此我也用这个…

Prompt提示词教程 | 提示工程指南 | 提示词示例 入门篇

在上一节中,我们介绍并给出了如何赋能大语言模型的基本示例。如果还没看而且是刚入门的同学建议看下,有个基本概念。 Prompt提示词教程 | 提示工程指南 | 提示工程简介https://blog.csdn.net/HRG520JN/article/details/138523705在本节中,我…

结合kimi chat的爬虫实战思路

背景 想钻研一下项目组件,找找之后的学习方向。不能自以为是,所以借着网开源项目网站上公布的项目内容看一下,那些是我可以努力去学习的(入门的)。首先需要获取相关内容,于是爬取整理。 任务1&#xff1a…

Unity与C#的关系

第一,我们首先需要知道Unity与C#的关系是什么? 第二,我们要明白为什么Unity会使用C#,而不是C? 第三,我们需要知道Unity是怎么使用C#的? 第一点: 先说结论:C#是Unity用…

【Verilog】big_small_cnt

通用大小计数器 timescale 1ns / 1ps // // Company: // Engineer: wengf // Create Date: // Design Name: // Module Name: big_small_cnt // Project Name: // Target Devices: // Tool Versions: // Description: // Dependencies: // Revision: // Revision 0…

一起刷C语言菜鸟教程100题(15-26含解析)

五一过的好快,五天假期说没就没,因为一些事情耽搁到现在,不过还是要继续学习的,之后就照常更新,先说一下,这个100题是菜鸟教程里面的,但是有一些题,我加入了自己的理解,甚…

odoo实施之创建行业demo

创建数据库,添加公司数据 选择应用,获取15天免费试用 创建完成 设置客户公司logo 创建用户 更改用户语言 前置条件:配置邮件 开发模式下,额外信息 加载demo数据

Conda下Richdem包遇到问题

Conda中Richdem包遇到问题 文章目录 Conda中Richdem包遇到问题问题一报错解决 问题二报错解决 参考 问题一 报错 RichDEM 是一套数字高程模型 (DEM) 水文分析工具,这次打算用richdem进行地形分析,尝试在conda里面安装richdem包的…

VMware下Ubuntu的安装教程

文章目录 一、Ubuntu如何下载1.下载官方地址https://ubuntu.com/2.点选Ubuntu服务器版本3.点击下载Ubuntu服务器版本iso镜像二、VMware安装Ubuntu服务器系统1.创建虚拟机2.选择下载好的Ubuntu服务器镜像3.创建安装完成三、Ubuntu Server如何设置1.Ubuntu Server没有中文所以全都…

windows vscode设置扩展和缓存目录

vscode的扩展和缓存占了很大的空间,而且默认在C盘,很烦。。。 修改vscode快捷方式的目标处:"C:\Users\Nv9\AppData\Local\Programs\Microsoft VS Code\Code.exe" --extensions-dir "D:\Program Cache\VScode\extensions"…

sql注入练习

1.什么是SQL注入 SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,甚至篡改数据库 2.sql注入原理 攻击者注入一段包含注释符的SQL语…

kraken2 最新版安装,极简模式

kraken2 git clone https://github.com/DerrickWood/kraken2.gitcd kraken2./install_kraken2.sh /opt/krakenvim .bashrc ---------------- # Kraken export PATH"/opt/kraken:$PATH" ----------------source .bashrc Note: 不晓得是不是我设置了清华源&#xff0c…

Spring Boot集成Swagger快速入门Demo

1.什么是Swagger? Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。 主要作用: 使得前后端分离开发更加方便,有利于团队协作。(实际开发中,接口文档的内容会不停的…

kafka学习笔记(三、生产者Producer使用及配置参数)

1.简介 1.1.producer介绍 生产者就是负责向kafka发送消息的应用程序。消息在通过send()方法发往broker的过程中,有可能需要经过拦截器(Interceptor)、序列化器(Serializer)和分区器(Partitioner)的一系列作用后才能被真正的发往broker。 demo: public class Kafk…

【NodeMCU实时天气时钟温湿度项目 4】通过NTPClient库获取实时网络时间并显示在TFT屏幕上

今天是【实时天气时钟温湿度项目】第四专题,主要内容是:学习导入NTPClient库,通过这个库获取实时网络时间,显示在1.3寸TFT液晶屏幕上。此前三个专题,请选择查看以下链接。 第一专题内容,请参考 【N…

使用Docker安装MySQL5.7.36

拉取镜像并查看 docker pull mysql:5.7.36拉取成功后查看(非必须) docker images创建并设置宿主机 mysql 配置文件目录和数据文件目录 创建相关文件夹将容器中的mysql数据保存到本地,这样即使容器被删除,数据也不会丢失。 mkd…

牛客NC142 最长重复子串【中等 字符串 Java/Go】

题目 题目链接: https://www.nowcoder.com/practice/4fe306a84f084c249e4afad5edf889cc 思路 注意:题目给的时间复杂度是O(N^2)那么直接套用双重循环:外层循环i为假定起始重复子串的初始位置,内层循环的j为假定重复子串的结束位置…

每日一题5:Pandas-修改列

一、每日一题 一家公司决定增加员工的薪水。 编写一个解决方案,将每个员工的薪水乘以2来 修改 salary 列。 返回结果格式如下示例所示。 解答: import pandas as pddef modifySalaryColumn(employees: pd.DataFrame) -> pd.DataFrame:employees.loc[…

人工神经网络初步

大家好,这里是七七,由于各种比赛的缘故,使用了很多人工神经网络模型。但是很多的原理都不是很明白,就导致了不能灵活地运用┭┮﹏┭┮。为此,去看了些人工神经网络原理书,写下此专题。 在进入正文之前要先…