你还在用命令式编程?Python函数式编程让你的代码更优雅!

news2024/11/22 21:32:07

Python支持函数式编程,函数式编程是一种编程范式,它将计算机程序视为数学函数的组合。

文章目录

一、lambda表达式

lambda表达式的定义

lambda表达式的应用场景

lambda表达式的局限性

lambda表达式的高级用法

二、Python的高阶函数

高阶函数的定义

常用的高阶函数

函数作为参数

函数作为返回值

三、Functools模块

functools模块的介绍

partial()函数

lru_cache()函数

wraps()函数

cmp_to_key()函数

四、Python生成器

生成器的定义

生成器的工作原理

生成器的优点

生成器的应用场景

生成器的注意事项

五、Python装饰器

装饰器的定义

装饰器的工作原理

装饰器的应用场景

装饰器的注意事项

六、Python列表推导式和字典推导式

列表推导式的定义

列表推导式的工作原理

列表推导式的应用场景

字典推导式的定义

字典推导式的工作原理

字典推导式的应用场景

列表推导式和字典推导式的注意事项

七、Python中的函数式编程库

functools

itertools

toolz

fn.py

PyMonad


一、lambda表达式

lambda表达式是Python语言中的一个重要特性,它可以用于定义简单的匿名函数。lambda表达式通常用于高阶函数、列表推导式、字典推导式和装饰器等场景。需要注意的是,lambda表达式通常只适用于简单的函数定义,复杂的函数定义通常需要使用def语句来定义。

lambda表达式的定义

lambda表达式是一种匿名函数,可以在需要使用函数的地方定义一个简单的函数。lambda表达式的语法如下:

lambda arguments: expression

其中,arguments表示函数的参数列表,可以有多个参数,用逗号分隔;expression表示函数的返回值表达式,可以是任意的表达式。

以下是一个使用lambda表达式的示例代码:

my_list = [1, 2, 3, 4, 5]
result = map(lambda x: x*2, my_list)
print(list(result))

在上面的代码中,我们使用lambda表达式定义了一个匿名函数,并将其传递给了map()函数。

lambda表达式的应用场景

lambda表达式通常用于定义一次性使用的简单函数。例如,在使用map()、reduce()、filter()等高阶函数时,我们可以使用lambda表达式来定义映射、归约和过滤的函数。

以下是一个使用lambda表达式的示例代码:

my_list = [1, 2, 3, 4, 5]
result = filter(lambda x: x%2==0, my_list)
print(list(result))

在上面的代码中,我们使用lambda表达式定义了一个函数,用于过滤列表中的偶数元素,并将其传递给了filter()函数。

lambda表达式的局限性

lambda表达式通常只适用于简单的函数定义,复杂的函数定义通常需要使用def语句来定义。lambda表达式只能包含一个表达式,并且该表达式的结果将作为函数的返回值。在lambda表达式中不能使用语句或赋值操作符。

以下是一个不能使用lambda表达式的示例代码:

def my_function():
    print("My function")
    return 1

my_lambda = lambda: (print("My lambda"), 1)[1]
result = my_lambda()
print(result)

在上面的代码中,我们定义了一个函数my_function(),该函数包含了打印语句和返回语句。我们尝试使用lambda表达式来定义一个相同的函数,但是由于lambda表达式只能包含一个表达式,因此我们使用了一个三元表达式来模拟返回语句。

lambda表达式的高级用法

lambda表达式可以与其他Python的语言特性结合使用,例如列表推导式、字典推导式和装饰器等。

以下是一个使用lambda表达式和列表推导式的示例代码:

my_list = [1, 2, 3, 4, 5]
result = [(lambda x: x*2)(x) for x in my_list]
print(result)

在上面的代码中,我们使用lambda表达式和列表推导式创建了一个新的列表,该列表包含了原列表中每个元素的两倍。

二、Python的高阶函数

高阶函数是Python函数式编程中的重要概念,它可以使代码更加灵活,并且可以减少代码的重复。Python中常用的高阶函数包括map()、reduce()、filter()等。函数可以作为参数传递给其他函数,也可以作为返回值返回给调用者。需要注意的是,高阶函数通常需要使用lambda表达式来定义函数,lambda表达式可以用于定义简单的匿名函数。

高阶函数的定义

高阶函数是指可以接受函数作为参数或返回函数作为结果的函数。Python中内置了一些高阶函数,包括map()、reduce()、filter()等。

以下是一个使用map()函数的示例代码:

my_list = [1, 2, 3, 4, 5]
result = map(lambda x: x*2, my_list)
print(list(result))

在上面的代码中,我们使用map()函数将一个列表中的元素乘以2,并使用list()函数将结果转换为列表。

常用的高阶函数

Python中常用的高阶函数包括:

  • map()函数:接受一个函数和一个序列作为参数,将函数应用到序列中的每个元素,并返回一个新的序列。

以下是一个使用map()函数的示例代码:

my_list = [1, 2, 3, 4, 5]
result = map(lambda x: x*2, my_list)
print(list(result))

在上面的代码中,我们使用map()函数将一个列表中的元素乘以2,并使用list()函数将结果转换为列表。

  • reduce()函数:接受一个函数和一个序列作为参数,使用函数将序列中的元素归约为一个单独的值。

以下是一个使用reduce()函数的示例代码:

from functools import reduce

my_list = [1, 2, 3, 4, 5]
result = reduce(lambda x, y: x+y, my_list)
print(result)

在上面的代码中,我们使用reduce()函数将一个列表中的元素累加,并返回累加的结果。

  • filter()函数:接受一个函数和一个序列作为参数,使用函数过滤出序列中符合条件的元素,并返回一个新的序列。

以下是一个使用filter()函数的示例代码:

my_list = [1, 2, 3, 4, 5]
result = filter(lambda x: x%2==0, my_list)
print(list(result))

在上面的代码中,我们使用filter()函数过滤了一个列表中的偶数元素,并使用list()函数将结果转换为列表。

函数作为参数

在Python中,函数可以作为参数传递给其他函数。这种用法可以使代码更加灵活,并且可以减少代码的重复。

以下是一个使用函数作为参数的示例代码:

def my_function(x):
    return x*2

def apply_function(f, lst):
    return [f(x) for x in lst]

my_list = [1, 2, 3, 4, 5]
result = apply_function(my_function, my_list)
print(result)

在上面的代码中,我们定义了一个函数my_function(),用于将一个数乘以2。然后我们定义了一个函数apply_function(),该函数接受一个函数和一个列表作为参数,将函数应用于列表中的每个元素,并返回一个新的列表。最后,我们将my_function()函数和my_list列表传递给apply_function()函数,并将其结果保存到result变量中。

函数作为返回值

在Python中,函数也可以作为返回值返回给调用者。这种用法可以使代码更加灵活,并且可以根据不同的情况返回不同的函数。

以下是一个使用函数作为返回值的示例代码:

def get_math_function(operation):
    if operation == '+':
        return lambda x, y: x+y
    elif operation == '-':
        return lambda x, y: x-y
    elif operation == '*':
        return lambda x, y: x*y
    elif operation == '/':
        return lambda x, y: x/y

my_function = get_math_function('*')
result = my_function(2, 3)
print(result)

在上面的代码中,我们定义了一个函数get_math_function(),该函数根据参数返回不同的函数。然后我们调用get_math_function()函数,传递了参数'*',并将返回的函数保存到my_function变量中。最后,我们调用my_function()函数,将2和3作为参数传递进去,并将结果保存到result变量中。

三、Functools模块

functools模块是Python标准库中的一个模块,提供了一些高阶函数和函数式编程工具。该模块可以用于实现函数柯里化、偏函数、缓存等功能。functools模块中常用的函数包括partial()函数、lru_cache()函数、wraps()函数、cmp_to_key()函数等。需要注意的是,functools模块中的函数通常需要和其他函数一起使用,以便实现更加复杂的功能。

functools模块的介绍

functools模块是Python标准库中的一个模块,提供了一些高阶函数和函数式编程工具。该模块可以用于实现函数柯里化、偏函数、缓存等功能。

以下是一个使用functools模块的示例代码:

import functools

def my_function(x, y):
    return x*y

my_partial = functools.partial(my_function, y=2)
result = my_partial(3)
print(result)

在上面的代码中,我们使用functools模块中的partial()函数创建了一个偏函数my_partial,该偏函数将my_function函数的第二个参数固定为2。然后我们调用my_partial()函数,将3作为my_function()函数的第一个参数传递进去,并将结果保存到result变量中。

partial()函数

partial()函数是functools模块中的一个函数,用于创建偏函数。偏函数是指将一个函数的部分参数固定,返回一个新的函数。

以下是一个使用partial()函数的示例代码:

import functools

def my_function(x, y):
    return x*y

my_partial = functools.partial(my_function, y=2)
result = my_partial(3)
print(result)

在上面的代码中,我们使用partial()函数创建了一个偏函数my_partial,该偏函数将my_function函数的第二个参数固定为2。然后我们调用my_partial()函数,将3作为my_function()函数的第一个参数传递进去,并将结果保存到result变量中。

lru_cache()函数

lru_cache()函数是functools模块中的一个函数,用于创建一个缓存,可以缓存函数的调用结果,避免重复计算。

以下是一个使用lru_cache()函数的示例代码:

import functools

@functools.lru_cache()
def my_function(x):
    print("Calculating...")
    return x*x

result = my_function(2)
print(result)

result = my_function(2)
print(result)

在上面的代码中,我们使用lru_cache()函数创建了一个缓存,用于缓存my_function()函数的调用结果。然后我们调用my_function()函数,将2作为参数传递进去,并将结果保存到result变量中。在第二次调用my_function()函数时,由于之前已经计算过了,所以直接从缓存中获取结果,不再进行计算。

wraps()函数

wraps()函数是functools模块中的一个函数,用于定义一个装饰器,该装饰器用于将被装饰函数的__name__、doc、__module__等属性复制到装饰器函数中。

以下是一个使用wraps()函数的示例代码:

import functools

def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print("Before...")
        result = func(*args, **kwargs)
        print("After...")
        return result
    return wrapper

@my_decorator
def my_function(x):
    """
    This is my function.
    """
    return x*x

result = my_function(2)
print(result)
print(my_function.__name__)
print(my_function.__doc__)

在上面的代码中,我们定义了一个装饰器my_decorator,该装饰器用于在被装饰函数执行前后打印一些信息。然后我们使用wraps()函数将被装饰函数的属性复制到装饰器函数中。最后,我们使用my_decorator装饰了一个函数my_function,并调用该函数。

cmp_to_key()函数

cmp_to_key()函数是functools模块中的一个函数,用于将旧式的比较函数转换为键函数。在Python 2.x中,比较函数用于比较两个元素的大小;在Python 3.x中,比较函数已经被移除,取而代之的是键函数。

以下是一个使用cmp_to_key()函数的示例代码:

import functools

def my_compare(x, y):
    if x < y:
        return -1
    elif x > y:
        return 1
    else:
        return 0

my_list = [5, 3, 2, 8, 7]
my_key = functools.cmp_to_key(my_compare)
my_list.sort(key=my_key)
print(my_list)

在上面的代码中,我们定义了一个旧式的比较函数my_compare,用于比较两个元素的大小。然后我们使用cmp_to_key()函数将该函数转换为键函数my_key。最后,我们使用my_list.sort()函数,并将my_key作为参数传递进去,对my_list进行排序。

四、Python生成器

生成器是一种特殊的迭代器,可以动态地生成数据,可以通过函数或生成器表达式来创建。生成器具有惰性计算、无限序列、流式处理等优点,可以用于处理大量数据、生成无限序列、实现协程和异步编程等。需要注意的是,生成器只能迭代一次、不能使用切片操作、需要及时关闭等问题。

生成器的定义

生成器是一种特殊的迭代器,它可以在循环中动态地生成数据,而不是在一开始就生成所有数据。生成器可以通过函数或生成器表达式来创建。

以下是一个使用生成器表达式创建生成器的示例代码:

my_generator = (x*x for x in range(10))
print(list(my_generator))

在上面的代码中,我们使用生成器表达式创建了一个生成器my_generator,该生成器可以动态地生成0到9的平方,并使用list()函数将其转换为列表。

生成器的工作原理

生成器的工作原理可以简单地描述为:每次调用生成器的__next__()方法时,它会执行到下一个yield语句,并返回该语句的值。当所有的yield语句都执行完毕后,生成器会自动抛出StopIteration异常,表示迭代结束。

以下是一个使用yield语句创建生成器的示例代码:

def my_generator():
    for i in range(10):
        yield i*i

gen = my_generator()
print(list(gen))

在上面的代码中,我们使用yield语句在函数中创建了一个生成器。每次调用生成器的__next__()方法时,它会执行到下一个yield语句,并返回该语句的值。最后,我们使用list()函数将生成器转换为列表。

生成器的优点

生成器具有以下优点:

  • 惰性计算:生成器不会一开始就生成所有数据,而是在需要时才生成数据,可以节省大量的内存空间。
  • 无限序列:生成器可以用来生成无限序列,例如斐波那契数列、素数序列等。
  • 可以用于流式处理:生成器可以用于流式处理大量数据,例如读取大文件、网络数据等。

以下是一个使用生成器处理大文件的示例代码:

def read_file(file_path):
    with open(file_path) as f:
        for line in f:
            yield line.strip()

for line in read_file("large_file.txt"):
    process(line)

在上面的代码中,我们定义了一个生成器read_file(),用于读取大文件,每次返回一行数据。然后我们使用for循环遍历生成器,对每行数据进行处理。

生成器的应用场景

生成器可以用于以下场景:

  • 处理大量数据,例如大文件、网络数据等。
  • 生成无限序列,例如斐波那契数列、素数序列等。
  • 实现协程和异步编程,例如使用asyncio库实现异步IO操作。
  • 生成器还可以用于实现管道和过滤器模式,例如使用生成器实现Unix管道。

生成器的注意事项

生成器虽然有很多优点,但也需要注意以下事项:

  • 生成器只能迭代一次:生成器只能迭代一次,因为迭代完毕后会自动抛出StopIteration异常。
  • 生成器不能使用切片操作:由于生成器是惰性计算的,因此不能使用切片操作,否则会导致生成器提前终止。
  • 生成器需要及时关闭:生成器在使用完毕后需要及时关闭,否则可能会导致资源泄漏和内存泄漏等问题。

五、Python装饰器

装饰器是一种Python语言的语法糖,用于修改或增强函数或类的功能。装饰器本身是一个函数,接收一个函数作为参数,并返回一个新的函数,新函数在调用原函数前后执行一些额外的操作,最后返回原函数的返回值。装饰器可以用于记录日志、计时器、缓存、权限控制、重试机制等场景。使用装饰器时需要注意函数的定义和调用规则、装饰器的参数、嵌套使用、保留原函数的元信息等问题。

装饰器的定义

装饰器是一种Python语言的语法糖,用于修改或增强函数或类的功能。装饰器可以在不修改原函数或类的情况下,动态地给它们添加额外的功能。

以下是一个使用装饰器增强函数功能的示例代码:

def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    return wrapper

@my_decorator
def my_function():
    print("Inside function")

my_function()

在上面的代码中,我们定义了一个装饰器my_decorator,用于在函数调用前后打印一些信息。然后我们使用@my_decorator语法糖将装饰器应用到函数my_function上。

装饰器的工作原理

装饰器的工作原理可以简单地描述为:装饰器本身是一个函数,它接收一个函数作为参数,然后返回一个新的函数,新函数在调用原函数前后执行一些额外的操作,最后返回原函数的返回值。

以下是一个使用装饰器增强函数功能的示例代码:

def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    return wrapper

@my_decorator
def my_function():
    print("Inside function")

my_function()

在上面的代码中,装饰器my_decorator接收一个函数作为参数,并返回一个新的函数wrapper。在调用my_function()函数时,实际上调用的是wrapper()函数,该函数在调用原函数前后打印一些信息,并执行原函数。最后,wrapper()函数返回原函数的返回值。

装饰器的应用场景

装饰器可以用于以下场景:

  • 记录日志:可以使用装饰器记录函数的调用日志,例如记录函数的参数、返回值、执行时间等。
  • 计时器:可以使用装饰器实现一个计时器,用于计算函数的执行时间。
  • 缓存:可以使用装饰器实现一个缓存,缓存函数的调用结果,避免重复计算。
  • 权限控制:可以使用装饰器实现一个权限控制,限制只有特定的用户或角色才能调用函数。
  • 重试机制:可以使用装饰器实现一个重试机制,当函数调用失败时,自动重试多次。

以下是一个使用装饰器实现缓存功能的示例代码:

import functools

def cache(func):
    cache_dict = {}
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        key = args + tuple(kwargs.items())
        if key not in cache_dict:
            cache_dict[key] = func(*args, **kwargs)
        return cache_dict[key]
    return wrapper

@cache
def my_function(x, y):
    print("Calculating...")
    return x*y

print(my_function(2, 3))
print(my_function(2, 3))

在上面的代码中,我们定义了一个cache装饰器,用于缓存函数的调用结果。然后我们使用@cache语法糖将装饰器应用到函数my_function上。

装饰器的注意事项

使用装饰器时需要注意以下事项:

  • 装饰器本身也是一个函数,因此需要遵循函数的定义和调用规则。
  • 装饰器可以接收参数,但是需要在装饰器内部再定义一层函数来接收参数。
  • 装饰器可以嵌套使用,但是需要注意函数调用顺序。
  • 装饰器可以使用functools.wraps()函数来保留原函数的元信息,例如函数名、文档字符串等。

六、Python列表推导式和字典推导式

列表推导式和字典推导式是一种简洁而强大的Python语法,用于生成新的列表和字典。它们的工作原理都是通过一个for循环迭代一个可迭代对象,对每个元素进行操作,并将结果添加到一个新的列表或字典中。它们可以用于筛选数据、转换数据、生成新列表或字典等场景。使用列表推导式和字典推导式时需要注意代码的可读性、if语句的位置和条件、for语句的顺序等问题。

列表推导式的定义

列表推导式是一种简洁而强大的Python语法,用于生成新的列表。列表推导式通常使用一行代码就可以完成复杂的列表操作。

以下是一个使用列表推导式生成新列表的示例代码:

my_list = [x*x for x in range(10)]
print(my_list)

在上面的代码中,我们使用列表推导式生成一个新的列表,该列表包含0到9的平方。

列表推导式的工作原理

列表推导式的工作原理可以简单地描述为:通过一个for循环迭代一个可迭代对象,对每个元素进行操作,并将结果添加到一个新的列表中。

以下是一个使用列表推导式生成新列表的示例代码:

my_list = [x*x for x in range(10)]
print(my_list)

在上面的代码中,for循环迭代0到9的整数,对每个整数进行平方操作,并将结果添加到一个新的列表中。

列表推导式的应用场景

列表推导式可以用于以下场景:

  • 筛选数据:可以使用列表推导式根据条件筛选列表中的数据。
  • 转换数据:可以使用列表推导式将列表中的数据进行转换,例如将字符串列表转换为整数列表。
  • 生成新列表:可以使用列表推导式生成新的列表,例如生成斐波那契数列、素数序列等。

以下是一个使用列表推导式将列表中的字符串转换为整数的示例代码:

my_list = ["1", "2", "3", "4", "5"]
new_list = [int(x) for x in my_list]
print(new_list)

在上面的代码中,我们使用列表推导式将字符串列表my_list中的元素转换为整数,并将结果存储到新的列表new_list中。

字典推导式的定义

字典推导式是一种简洁而强大的Python语法,用于生成新的字典。字典推导式通常使用一行代码就可以完成复杂的字典操作。

以下是一个使用字典推导式生成新字典的示例代码:

my_dict = {x: x*x for x in range(10)}
print(my_dict)

在上面的代码中,我们使用字典推导式生成一个新的字典,该字典包含0到9的整数及其平方。

字典推导式的工作原理

字典推导式的工作原理可以简单地描述为:通过一个for循环迭代一个可迭代对象,对每个元素进行操作,并将结果添加到一个新的字典中。

以下是一个使用字典推导式生成新字典的示例代码:

my_dict = {x: x*x for x in range(10)}
print(my_dict)

在上面的代码中,for循环迭代0到9的整数,对每个整数进行平方操作,并将结果添加到一个新的字典中。

字典推导式的应用场景

字典推导式可以用于以下场景:

  • 筛选数据:可以使用字典推导式根据条件筛选字典中的数据。
  • 转换数据:可以使用字典推导式将字典中的数据进行转换,例如将字典中的字符串值转换为整数值。
  • 生成新字典:可以使用字典推导式生成新的字典,例如将一个列表转换为字典,其中列表元素作为字典的键,另一个可迭代对象中的元素作为字典的值。

以下是一个使用字典推导式将字典中的字符串值转换为整数值的示例代码:

my_dict = {"a": "1", "b": "2", "c": "3", "d": "4", "e": "5"}
new_dict = {k: int(v) for k, v in my_dict.items()}
print(new_dict)

在上面的代码中,我们使用字典推导式将字典my_dict中的字符串值转换为整数值,并将结果存储到新的字典new_dict中。

列表推导式和字典推导式的注意事项

使用列表推导式和字典推导式时需要注意以下事项:

  • 列表推导式和字典推导式可以嵌套使用,但是需要注意代码的可读性。
  • 列表推导式和字典推导式可以使用if语句进行筛选,需要注意if语句的位置和条件。
  • 列表推导式和字典推导式可以使用多个for语句进行嵌套,需要注意for语句的顺序。

七、Python中的函数式编程库

Python中的函数式编程库有很多,每个库都有其特点和适用场景。其中,functools和itertools是Python标准库的一部分,可以直接导入使用,功能相对简单;而toolz、fn.py和PyMonad需要安装,提供了一些高级函数式编程功能,适用于一些复杂的函数式编程场景。使用函数式编程库时,需要根据具体场景选择适当的库,以达到最佳的编程效果。

以下是一些常用的函数式编程库及其功能作用、使用区别、使用场景、优缺点等介绍:

functools

  • 功能作用:提供了一些高阶函数,例如partial、reduce、wraps等,可以方便地操作函数。
  • 使用区别:functools是Python标准库的一部分,无需安装,可以直接导入使用。
  • 使用场景:可以用于函数的柯里化、函数的装饰器、函数的元信息保留等场景。
  • 优点:无需安装,使用方便,功能丰富。
  • 缺点:功能相对简单,不适用于一些复杂的函数式编程场景。

itertools

  • 功能作用:提供了一些迭代器函数,例如product、permutations、combinations等,可以方便地生成迭代器。
  • 使用区别:itertools是Python标准库的一部分,无需安装,可以直接导入使用。
  • 使用场景:可以用于生成排列组合、笛卡尔积、循环迭代等场景。
  • 优点:无需安装,使用方便,功能丰富。
  • 缺点:只提供了一些迭代器函数,不适用于一些复杂的函数式编程场景。

toolz

  • 功能作用:提供了一些高阶函数,例如curry、compose、pipe等,可以方便地操作函数。
  • 使用区别:toolz需要安装,可以使用pip命令安装,例如pip install toolz。
  • 使用场景:可以用于函数的柯里化、函数的组合、懒计算等场景。
  • 优点:提供了一些高级函数式编程功能,适用于一些复杂的函数式编程场景。
  • 缺点:需要安装,使用稍微复杂一些。

fn.py

  • 功能作用:提供了一些高阶函数,例如curry、compose、zip_with等,可以方便地操作函数。
  • 使用区别:fn.py需要安装,可以使用pip命令安装,例如pip install fn.
  • 使用场景:可以用于函数的柯里化、函数的组合、懒计算、惰性序列等场景。
  • 优点:提供了一些高级函数式编程功能,适用于一些复杂的函数式编程场景。
  • 缺点:需要安装,使用稍微复杂一些。

PyMonad

  • 功能作用:提供了一些基本的单子类型,例如Maybe、Either、State等,可以方便地实现单子模式。
  • 使用区别:PyMonad需要安装,可以使用pip命令安装,例如pip install PyMonad。
  • 使用场景:可以用于实现单子模式、函数式编程中的异常处理、状态管理等场景。
  • 优点:提供了一些基本的单子类型,方便实现单子模式。
  • 缺点:功能相对简单,不适用于一些复杂的函数式编程场景。

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

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

相关文章

(链表) 剑指 Offer II 022. 链表中环的入口节点 ——【Leetcode每日一题】

❓剑指 Offer II 022. 链表中环的入口节点 难度&#xff1a;中等 给定一个链表&#xff0c;返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环&#xff0c;则返回 null。 为了表示给定链表中的环&#xff0c…

Python补充笔记4-面向对象

目录 一、编程思想​ 二、类与对象​ 三、类的创建​ 四、对象的创建​ 五、类属性、类方法、静态方法​ 六、动态绑定属性和方法​ 七、知识点总结 八、面向对象的三大特征 1.封装 2.继承​ 3.多态 九、方法重写 十、object类 十一、特殊方法和特殊属性 1.dict/len/add​ 2.…

python调用百度ai将图片识别为表格excel

python调用百度ai将图片识别为表格excel ocr ocr 百度ai官方文档&#xff1a;https://ai.baidu.com/ai-doc/OCR/Ik3h7y238 import requests import json import base64 import time文档&#xff1a;https://ai.baidu.com/ai-doc/OCR/Ik3h7y238 # 获取access_token def get_acc…

学习笔记--TCP/IP协议

TCP/IP协议 TCP (Transmission Control Protocol)传输控制协议&#xff0c;传输层协议。 一、协议的分层 ISO网络层分为7层 二、分层的作用 具体通信情况&#xff1a; 三、报文传输 三次握手连接&#xff0c;四次挥手释放 参考链接&#xff1a; https://zhuanlan.zhih…

直播带货app开发开发流程分析

随着小视频管理体系愈来愈变成人们的生活中的一部分&#xff0c;也随之短视频卖货逐步形成岗位内主流的转现方式&#xff0c;将短视频平台生产制造变成短视频带货体系计划愈来愈多&#xff0c;那样&#xff0c;把小视频管理体系开发设计变成短视频带货体系必须两步&#xff1f;…

在Microsoft Excel中如何快速合并表格

在 Excel 中分析数据时&#xff0c;在一个工作表中收集所有必要信息的频率是多少&#xff1f;几乎从来没有&#xff01;当不同的数据分散在许多工作表和工作簿中时&#xff0c;这是一种非常常见的情况。幸运的是&#xff0c;有几种不同的方法可以将多个表中的数据组合成一个表&…

【python】爬楼梯—递归分析(超级详细)

爬楼梯—递归分析 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 注意&#xff1a;给定 n 是一个正整数。 示例 1&#xff1a; 输入&#xff1a; 1 输出&#xff1a; 1 解释&#xff1a; 有一种方…

GPT和MBR的区别

磁盘分区是操作系统管理磁盘数据的一项非常重要的功能。在分区时&#xff0c;用户需要选择一种分区表格式来组织磁盘上的分区&#xff0c;这也就是GPT和MBR两种分区表格式的由来。在本文中&#xff0c;将详细探讨GPT和MBR分区表格式的区别和如何选择它们。 1. MBR和GPT分区表格…

electron-egg 加密报错

electron框架&#xff1a;electron-egg 解决方式 npm uninstall bytenode npm install bytenode1.3.6node:internal/modules/cjs/loader:928 throw err; ^ Error: Cannot find module ‘node:assert/strict’ Require stack: D:\electron-egg-test\new-electron-egg\electr…

勘探开发人工智能技术:断层识别

1 断层识别 断层是地下岩层在受到挤压或拉伸力作用下,因脆性变形而形成的地层错断,是一种重要的地质构造特征。断层检测和解释是从地震剖面中认识岩层结构和储层特性的重要步骤。 1.1 数据描述 合成地震数据: 每一个合成地震数据都是由地质模型的反射系数与雷克子波进行褶…

Vite 4.4 正式版发布,全面拥抱 Lightning CSS

一、什么是 Vite Vite 是由 Evan You 推出的下一代前端构建工具&#xff0c;是官方 Vue CLI 的替代品&#xff0c;速度非常快。Vite 利用原生 ESM 并使用 Rollup 处理开发和打包工作。 从功能上讲&#xff0c;它的工作方式类似于预配置的 webpack 和 webpack-dev-server&#…

软考_软件设计师(中级)

视频链接&#xff1a;&#xff08;zst_2001&#xff09; https://www.bilibili.com/read/cv18526892?spm_id_from333.999.0.0 文章目录 1、计算机系统2、程序设计语言3、知识产权4、数据库5、面向对象6、UML7、设计模式8、操作系统9、结构化开发10、软件工程11、信息安全&…

【MCU学习】RTthread工程介绍

RT-Thread架构 RT-Thread诞生于2006年&#xff0c;是一款以开源、中立、社区化发展起来的物联网操作系统。 RT-Thread主要采用 C 语言编写&#xff0c;浅显易懂&#xff0c;且具有方便移植的特性&#xff08;可快速移植到多种主流 MCU 及模组芯片上&#xff09;。RT-Thread把面…

Ubuntu18.04安装Autoware1.15(解决Openplanner无法绕障的问题:Openplanner2.5)

文章目录 一、下载Autoware1.15源码二、安装依赖三、修改CUDA版本四、编译以及报错解决编译&#xff08;1&#xff09;报 undefined reference to cv::Mat::Mat() 的错就按照下面方式改相应包&#xff1a;&#xff08;2&#xff09;遇到报错&#xff1a;&#xff08;3&#xff…

opencv-20 深入理解HSV 色彩空间(通过指定,标记颜色等来拓展ROI区域)

RGB 色彩空间是一种被广泛接受的色彩空间&#xff0c;但是该色彩空间过于抽象&#xff0c;我们不能够直接通过其值感知具体的色彩。 我们更习惯使用直观的方式来感知颜色&#xff0c;HSV 色彩空间提供了这样 的方式。 通过 HSV色彩空间&#xff0c;我们能够更加方便地通过色调、…

web APIs-练习一

轮播图点击切换&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"…

Servlet——使用Servlet编程的基本流程。

文章目录 前言一、创建项目创建Maven项目介绍Maven项目 二、引入依赖三、创建目录四、编写代码五、打包六、部署七、验证总结 前言 本人是一个普通程序猿!分享一点自己的见解,如果有错误的地方欢迎各位大佬莅临指导,如果你也对编程感兴趣的话&#xff0c;互关一下&#xff0c;…

软件测试面试题及答案【史上最全】

以下是软件测试相关的面试题及答案&#xff0c;欢迎大家参考! 1、你的测试职业发展是什么? 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&…

微信小程序开发使用echarts报错Cannot read property ‘getAttribute‘ of undefined

如图&#xff0c;我在小程序圈中的区域渲染echarts图标报错了&#xff0c;报错提示Cannot read property getAttribute of undefined 这里的canvas &#xff0c;width ,height,dpr获取为 undefined 分析问题&#xff1a; 初始化图表时传递错误的参数&#xff1a; 在 onShow 生…

靶向RNA-seq全面解决方案和加速分析,只看这篇就够了!

背景 RNA-seq&#xff0c;即通过高通量测序技术进行的转录组测序分析技术。最初作为研究mRNA&#xff0c;small RNA&#xff0c;non-coding RNA 等表达水平、表达差异基因的应用&#xff0c;在过去的十几年内迅速发展。而今&#xff0c; RNA-seq 在转录本变异、基因融合、可变…