[转载] Python 递归 深入理解递归 Python递归剖析,绝对让你看懂!

参考链接: Python | print()中的结束参数

目录

 递归剖析 递归的两个过程 return 返回值 详解

    递归思路二分法和递归尾递归递归练习题

  

 

 

 

递归剖析 

递归真的很重要,之前学的时候,学的一知半解,以为真正了解,每次想到递归,就记得一句:返回给函数的调用者,嗯?函数调用者,你是说外部,还是内部啊?疑问太多了,还有就是被告知一句:递归能解决的问题,循环都能解决,所以就更加不重视递归了!直到接触算法后,在解决问题时,最快,最容易理解的解法就是递归,但是此时的递归却是看不太懂为什么要这样做!我先来说下,在算法中遇到可以用递归轻松完成的:希尔排序、归并排序、快速排序、反转链表及各种反转问题、二叉树的深度遍历、二叉树的各种题基本可以用、全排列…还有算法步骤里需要用到,太多了,所以,递归非常重要!“To iterate is human, to recurse divine 迭代是人,递归是神”,接下来,我也是看了很多算法书和视频,重点来整理下递归! 

 递归的两个过程 

首先“递归”包括两个过程:递“去”的过程,“归”回的过程!先从一个简单的递归函数讲起 

def di_gui(n):

    print(n, "<===1====>")

    if n > 0:

        di_gui(n - 1)

    print(n, '<===2====>')

 

 

di_gui(5) # 外部调用后打印的结果是?

 

 递归的执行过程:首先,递归会执行“去”的过程,只需要满足终止条件,就会一直在函数内,带着更新的参数,调用函数自身,注意:到内部调用函数, 以下面的代码不会被执行,而是暂停阻塞;此时 随着函数每调用一次自身,还没有触发 返回值和到达终止条件,等同于在原来的基础上不断“向下/向内”开辟新的内存空间,记住,每次调用一次函数,就不是处在同一空间(想象下《盗梦空间》里的情景,梦中梦,都是处于不同的空间)   什么时候“递”去的过程结束?记住有两种情况>>> 一是:当前这层空间函数全部执行结束(终止条件),二是:执行到了return 返回值,直接返回;  重点来理解下,首先是一,看上面的列子,例子中没有return,但是不断的调用后,最终还是停止了,因为最后n=0时,di_gi(0)还是去调用,从上往下执行时,遇到if n>0 它被终止了,走不下去了,表明,自己能到达的这层空间已经全部执行完毕;接下来请原地返回吧,返回到哪里?返回到函数的调用者,好我们返回到 di_gui(0),把“到内部调用函数” 以下的代码全部执行完;执行完,看代码走到末尾,以为走出了最外层函数?注意了,此时它所处的空间并不是最外层哦,因为之前它被调用就在空间里面,所以回到的是 di_gui(1)的这一层空间,现在才是真正的开始“回”,所以继续把di_gui(1)的这一层空间,“到内部调用函数”以下的代码全部执行完,回到di_gui(2)的这一层空间…直到到达最开始 从外部调用,让参数5进入的最外层空间位置,才走出来!表示《盗梦空间》里,柯布醒了!  回来看下,代码输出的结果:5 4 3 2 1 00 1 2 3 4 5 ( 注意00这两个是在同一层空间哦)   从内存角度(本质)来分析:每调用一次函数,都会单独开辟一份栈帧空间,递归函数就是不停的开辟和释放栈帧空间的过程,具体来理解下:一个普通函数从执行到结束,就是一个开辟空间和释放空间的过程;而递归函数是在调用最外层函数时,先开辟一个最外层空间,每调用一次自身,就会在最外层空间内,再自己开辟本次的空间(所以递归耗内存)(还有一种说法是,不断的本次空间的基础上再开辟空间,等于是不断的嵌套,其实这两种说法本质上是一样的,因为信息都可以做到不共享),空间之间如果不通过参数传递或者用return 返回值,信息是不共享的,如下图↓↓↓  

  

 递归的数据共享情况:递归每一层间的数据是独立的,不共享,但是可以通过参数或者返回值来形成共享,参数具体在传入的是“引用类型”(比如列表)  递归 必须要有一个出口,如果没有出口就会重复调用,不断的开辟栈帧空间  

# 获取最大递归层数:

import sys

res=sys.getrecursionlimit()

print(res) # 结果:1000

# sys.setrecursionlimit(800) 可以自己设置最大递归层数

 

解释含有 return 返回值的递归,记住 return的返回流程是:先计算,再返回 ,来看下一段求阶乘的代码: 

def jie_cheng(n):

    if n <= 1:

        return 1

    return n * jie_cheng(n - 1)

    

print(jie_cheng(5))

 

 

return 是返回到函数调用者,递归函数和普通函数也是一样的,所以递归最后一层空间走到尽头(一是:指向完毕,二是:遇到return,回顾一下而已)遇到return,就要开始返回了,返回到它的调用者(即是阻塞的位置),直到回到最外层空间如果上面的内容看懂了的话,试着解析下:下面这段代码的执行流程 

def get_num(num):

    if num > 2:

        get_num(num - 1)

    print(num)

 

 

get_num(4) # 输出结果为:2 3 4

 

 

 

 代码变化一下: 

 

def get_num(num):

    if num > 2:

        get_num(num - 1)

    else:

        print(num)

 

 

get_num(4) # 输出结果为 2

 

'''

解析一下:加了else后,首先代码区有两个分支,

在num>2时,执行会有递归,当n=4 是开辟一层空间;

n=3时开辟一层空间,此时 get_num(2) 再开辟一个空间,

当它从上往下执行过程中,在他本层空间遇到if num>2 不成立,所以走分支 else,直接打印出来;

此时代码还没结束,回到上一层空间,num=3, num>2 已经进入了if 不会走else,

num=4 也不会走else,所以这两层空间没有值输出!

'''

 

 return 返回值 详解 

上面这一大部分,就算是递归入门了,接下来才刚刚开始哦!还要继续讲 return ;先来看下这几段代码:求全排列的一部分递归代码,试着分别写出运行结果,并依次分析原因↓↓↓ 

# 例1:

def fullpermutation(list):

    if list is None:

        return None

    if len(list) == 1:

        return [list]

    res = []

    pivot = list[0]

    remain = fullpermutation(list[1:])

    print(remain)

 

 

print(fullpermutation([1, 2, 3]))  

'''

输出结果为:

[[3]]

None

None

'''

 

递归只会在两种情况下触发“回”的过程,上述是在最后一层空间是碰到了return,所以给回到它的调用处(阻塞处),因为return会给调用者返回一个值,所以在本层空间,remain接收到了一个值:[[3]];接着执行下面的代码,即是打印remain,所以输出“[[3]]”,执行完print,等于回到了上一层空间,又到了调用处(阻塞处),那么这层空间还有返回值吗?答案是没有,所以“最后一层空间是碰到了return 给它返回的值 只会给最后一层使用”,所以接下来两层都是打印空! 

# 例2:

def fullpermutation(list):

    if list is None:

        return None

    if len(list) == 1:

        return [list]

    res = []

    pivot = list[0]

    return fullpermutation(list[1:])

 

 

print(fullpermutation([1, 2, 3]))

'''

输出结果为:

[[3]]

'''

 

这次是,在最后一层返回时,获得了一个返回值 [[3]] ,然后回到上一层时,前面又有return 表示需要把本层的返回值,返回到上层的接收处,重复,直到回到最外层,这个从底层传上来的返回值,一直传到了最外层,所以才打印出来的,只有最后一层,但是每次一层都获得了返回值,和例子1 后面两层没有返回值是不同的哦! 

# 例3:

def fullpermutation(list):

    if list is None:

        return None

    if len(list) == 1:

        return [list]

    res = []

    pivot = list[0]

    remain = fullpermutation(list[1:])

    print(list)

 

 

print(fullpermutation([1, 2, 3]))

'''

输出结果为:

[2, 3]

[1, 2, 3]

None

'''

 

最后一层碰到return,触发会的过程,回到调用处,执行阻塞处下面的代码,打印list,这个list是什么?它就是本层空间 参数的规模(因为代码写的是规模不断变小从[1,2,3]>>>[2,3]>>>[3]),显然,从最后一层回到上一层,此时规模是[2,3],所以打印list 就是[2, 3];接着继续回到上一层,即是最外层,规模是[1,2,3],所以打印[1, 2, 3],最后的None是因为最外层函数,没有返回值,所以才打印出None 

# 例4:

def fullpermutation(list):

    if list is None:

        return None

    if len(list) == 1:

        return [list]

    res = []

    pivot = list[0]

    remain = fullpermutation(list[1:])

    return list

 

 

print(fullpermutation([1, 2, 3]))

'''

输出结果为:

[1, 2, 3]

'''

 

依照上面的步骤,触发回的过程,只要没有到达最外层,return list 返回本层的规模(参数规模),那么这个返回值就会给本层的接收者 remain 不可能给最外层的接收者,虽然这里没有打印 remain的值,但是这里的remain和第一个列子中的remain,后面层数是有返回值的哦(下面例子就会体现),本例,返回到最外层时,list的本层规模为 [1,2,3] 最外层接收者接收到,然后打印出来,所以是[1,2,3] 

# 例5:

def fullpermutation(list):

    if list is None:

        return None

    if len(list) == 1:

        return [list]

    res = []

    pivot = list[0]

    remain = fullpermutation(list[1:])

    print(remain)

    return list

 

 

print(fullpermutation([1, 2, 3]))

'''

输出结果为:

[[3]]

[2, 3]

[1, 2, 3]

'''

 

看上面的例子,这次我们是打印了 remain,因为返回的过程中,指向阻塞处(调用处)下面的代码,每次return list 即是 在本层返回 当前的参数规模,所以 remain 是能接收本层的返回值的,所以会打印 [[3]] ,[2, 3] ;最后 [1, 2, 3] 是最外层打印的 

# 例6:

def fullpermutation(list):

    if list is None:

        return None

    if len(list) == 1:

        return [list]

    res = []

    pivot = list[0]

    remain = fullpermutation(list[1:])

    print(remain)

    print(list)

    return list

 

 

print(fullpermutation([1, 2, 3]))

'''

输出结果为:

[[3]]

[2, 3]

[2, 3]

[1, 2, 3]

[1, 2, 3]

'''

 

 这个,就是所有的融合;通过上面的代码我们来总结下return的返回值:最后一层遇到的return 需要执行 回的过程,此时的返回值 值会返回给最后的调用处的接收者;然后执行 阻塞处下面的代码时,如果又遇到return 这里的返回值,如果没有到达最外层,都是给本层的接收者!为什么要大费周章的讲这个,是因为我们在写递归时,往往不清楚return 要怎么写,已及它的返回值是什么?接下来就要看下return 如何解决问题的  请用递归完成一个字符串的反转,输入字符串“abcd”,完成翻转成“dcba” 除了递归,我们可以直接用字符串的切片来完成,如下,但是这里是要讲递归的思想,不体现方法优劣!  

s="abcd"

print(s[::-1])

 

想一下递归的思路该怎么做? 思路一:按照上面的例子,不断的划分子规模,我们选的是划分原字符串的规模,都是往后截取的,比如第一次参数s=“abcd” 我们取参数s[1:] ,不断调用函数,每次传入参数为:‘bcd’ ‘cd’ ‘d’ ,这样最后一层返回d 我们能拿到最后一个值,然后最后一个返回值d 加上 当前规模的第一个值,就完成了反转,具体代码如下: 

def str_reverse(s):

    if len(s) <= 1: # 递归出口

        return s

    # last = str_reverse(s[1:])

    # return last + s[0]

    return str_reverse(s[1:]) + s[0] # 每次返回最后一层的值,加上当前规模的第一个值

 

思路二:改变下子规模,我们这次不划分原字符串,而是从它的索引下手,传入最后一个元素的索引,不断去递归索引的值,这时,变的是end的值,从 3 到 2 1 0,到0时触发回的过程,返回当前索引的值,即是 a (不断向前取值),这时我们再加上当前层的s,因为没有划分s所以s每一层都是等于‘abcd’的,我们每次取当前end索引指向的字符串的值,等于从前往后遍历字符串 ‘abcd’ ,两部分链接起来,就完成了反转:每次的返回值为 a, ba , cba, dcba, 

def reve(str, end):

    if end == 0:

        return "" + str[0]

    last = str[end] + reve(str, end - 1)

    return last

 

 

s = "abcd"

print(reve(s, len(s) - 1))

 

 两种做法都用到return,而是还有重要的递归思路,下面就来看看递归要用什么思路来解  来试下“反转链表”如何用递归做,首先对于一个单链表,要对它反转,我们的思路依旧可以通过不断向后划分子规模,找到它的最后一个结点,然后从后往前依次改变每个结点的指向,让最初的头结点变成尾结点,让它最后指向None;那么具体步骤是:用递归找到最后一个结点,我们可以通过前一个结点的next区域,不断递归,找到下一个结点,直到当前结点的next是None,说明它就是最后一个结点,这也是我们递归的出口,那么依次让它返回,同时改变指向,就完成了,具体看下面的图解:  

class ListNode: 

    def __init__(self, x):

        self.val = x

        self.next = None

 

 

class Solution:

    def ReverseList(self, pHead):

        if pHead is None: # 判断传入的头结点是否为空

            return None

        if pHead.next is None: # 如果只有一个结点,直接返回结点;同时也是递归的出口

            return pHead

        last_node = self.ReverseList(pHead.next) # last_node永远只接收到了最后一个结点

        pHead.next.next = pHead # 后一个结点,指向前一个结点

        pHead.next = None # 前一个结点,在不同的层,先指向None,如果到达最外层也会指向None

        return last_node # 最后返回最后一个结点,表示反转成功

 

到达最后一层,触发回的过程,返回 last_node 结点给最后第四层,执行阻塞处下面的代码,因为pHead.next.next 是None,它不用改变也行,直接到 return last_node 把 last_node给第三层用… 第三层获得 last_node ,执行阻塞处下面的代码,改变指向,pHead.next.next 是“5结点”,它的指针指向 pHead,即是上一个结点,然后上一个结点指向None;因为这里并不需要用一个temp 来保存前一个指针信息,表面上是断开链接,会丢掉数据,其实不会丢掉,因为他们不再同一层;可以用temp先保存前一个结点的数,这属于递归的写,在我的文章>>>反转链表多种解法 有提到,这里不细说!  直到 回到最外层,起初的头结点,自然会指向None,最后返回 last_node即可 这才是 链表反转 递归的详细过程,果然和我开始理解的不一样,当初怎么都无法理解,直到用断点调试,才发现真正的过程,是这样,大家可以用断点调试下,看下代码的具体过程,下面是测试代码: 

class ListNode:

    def __init__(self, x):

        self.val = x

        self.next = None

 

 

class Solution:

    def ReverseList(self, pHead):

        if pHead is None:

            return None

        if pHead.next is None:

            return pHead

        last_node = self.ReverseList(pHead.next)

        print(last_node.val)

        pHead.next.next = pHead

        pHead.next = None

        return last_node

 

    def print_list(self, node):  # 打印测试

        if node is None:

            return None

        while node:

            print(node.val, end="")

            node = node.next

        print()

 

 

if __name__ == '__main__':

    n1 = ListNode(1)  # 依次实例5个结点

    n2 = ListNode(2)

    n3 = ListNode(3)

    n4 = ListNode(4)

    n5 = ListNode(5)

    n1.next = n2  # 依次将结点链接起来,形成一个链表

    n2.next = n3

    n3.next = n4

    n4.next = n5

    n5.next = None

 

    obj = Solution()

    print(obj.ReverseList(n1).val)

    # obj.print_list(n1) # 1 2 3 4 5

    # obj.print_list(obj.ReverseList(n1))  # 5 4 3 2 1

 

递归思路 

 思想: 1.找到当前这个值与上一个值的关系 2.找到程序的出口 有个明确的结束条件 3.假设当前功能已经完成 每次进入更深一层递归时,问题规模相比上次递归都应有所减少  递归思路: (1)找重复:看哪一部分是 实现函数的变化;每次进入更深一层递归时,问题规模相比上次递归都应有所减少 (2)找变化:变化的量应该作为参数 (3)找边界(出口):终止条件  递归可以分为: (1)直接量+小规模子问题 (2)多个小规模子问题 (3) “切蛋糕”思维 (4)找递推公式,等价交换公式  

二分法和递归 

# 二分法一定是在排序好的数据里使用

 

lst = [33, 22, 44, 55, 66, 88, 77, 99, 101, 238, 345, 456, 567, 678, 789]

n = 76

lst.sort()

left = 0

right = len(lst) - 1

 

while left <= right:  # 条件是 开头<=结尾

    middle = (left + right) // 2

    if lst[middle] > n:  # 每次用对折后,中间的数和 查找对象比较

        right = middle - 1

    elif lst[middle] < n:

        left = middle + 1

    elif lst[middle] == n:

        print("找到了")

        break

else:

    print("这个数不在列表中")

 

# 递归函数来做

lst = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789]

 

 

def func(n, left, right):

    if left <= right:  # 边界

        mid = (left + right) // 2

        if n > lst[mid]:

            left = mid + 1

            func(n, left, right)  # 递归的入口,目的是再确定一次中间的位置

        elif n < lst[mid]:

            right = mid - 1

            func(n, left, right)

        elif n == lst[mid]:

            print("找到了")

            return  # 递归出口

    else:

        print("没有这个数")

        return  # 递归的出口

 

 

func(66, 0, len(lst) - 1)

 

# 升级:如果找到了要求的数,请返回它的索引

 

lst = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789]

 

 

def func(n, left, right):

    if left <= right:  # 边界

        mid = (left + right) // 2

        if n > lst[mid]:

            left = mid + 1

            return func(n, left, right)  # 每一层都要返回给上一层的调用者

        elif n < lst[mid]:

            right = mid - 1

            return func(n, left, right)

        elif n == lst[mid]:

            print("找到了")

            return mid  # 多层函数只会将返回值返回给上一层的调用者

    else:

        print("没有这个数")

        return -1

 

 

print(func(66, 0, len(lst) - 1))

 

尾递归 

尾递归(自己调用自己,且非表达式:把值放到参数中算)

 

 

>>>求斐波那契数列第n位是几?(尾递归做法)

 

def feibo(num, res, temp):

     #使用尾递归法求解斐波那契数量的第num个数字

     if num == 0:

          return res

     else:

          return feibo(num - 1, temp, res + temp)

 

print(feibo(10,0,1))

 

# 直接递归  尾递归 与 循环 的对比

 

import time

 

 

def Fib_recursion(num):

    '''

    直接使用递归法求解斐波那契数量的第num个数字

    '''

    if num < 2:

        return num

    return Fib_recursion(num - 1) + Fib_recursion(num - 2)

 

 

def Fib_tail_recursion(num, res, temp):

    '''

    使用尾递归法求解斐波那契数量的第num个数字

    '''

    if num == 0:

        return res

    else:

        return Fib_tail_recursion(num - 1, temp, res + temp)

 

 

def Fib_circle(num):

    '''

    直接使用循环来求解

    '''

    a = 0

    b = 1

    for i in range(1, num):

        c = a + b

        a = b

        b = c

    return c

 

 

if __name__ == '__main__':

    num_list = [5, 10, 20, 30, 40, 50]

    for num in num_list:

        start_time = time.time()

        print(Fib_recursion(num))

        end_time = time.time()

        print(Fib_tail_recursion(num, 0, 1))

        end_time2 = time.time()

        print(Fib_circle(num))

        end_time3 = time.time()

        print('正在求解的斐波那契数字下标为%s' % num)

        print('直接递归耗时为 :', end_time - start_time)

        print('尾递归调用耗时为:', end_time2 - end_time)

        print('直接使用循环耗时为:', end_time3 - end_time2)

 

递归练习题 

>>>打印f-e的数:

 

def pri(f, e):

    if f > e:

        return

    else:

        print(f)

        return pri(f + 1, e)

 

 

pri(1, 6)

 

 

>>>求一个列表的和:

def sum_lis(li, f):  # 如果单独是传入一个列表,它体现不了变化

    """

    :param li: 传入一个列表

    :param f: 列表起始位置

    :return: 列表和

    """

    if f == len(li) - 1:  # 表示起始位置也是结束位置,即只有一个元素

        return li[f]

 

    return li[f] + sum_lis(li, f + 1)

 

 

print(sum_lis([1, 2, 3, 4, 5], 0))

 

# 多引入一个 变化的参数,可以想到第一个元素加上剩下的元素,规模不断变小

 

# 需求:求 1+2+3+4........100 的和

num = 1

count = 0

while num <= 100:

    count += num

    num += 1

print(count)

 

'''

思路:

sum(1) + 2 +3.....100

sum(2) + 3........100

sum(3) + 4........100

...

sum(98)+99+100

sum(99) + 100

sum(100)

 

sum(100) = sum(99) + 100

sum(99) = sum(98) + 99

sum(98) = sum(97) + 98

.....

 

sum(2) = sum(1) + 2

 

sum(1) = 1

'''

# 用递归函数解决

def sum(num):

    if num == 1:  # 出口

        return 1

    return num + sum(num - 1)  # 一直返回sum(num-1)+num,每次递归调用,有return才能有返回值

 

 

print(sum(100))

 

>>>需求:打印斐波那契数列

def fibo(num):  # 参数是表示第n个斐波那契数,函数整体表示获取斐波那契数列中第n个数字的值

    if num == 1 or num == 2:  # 第一个和第二个都是1

        return 1  # 返回1,出口

    return fibo(num - 1) + fibo(num - 2)  # 规律,后一项加上后两项,就等于斐波那契数列第n个数字的值

 

 

if __name__ == '__main__':

    list_num = []  # 创建一个空列表,开始

    for i in range(1, 21):  # 遍历1-20

        list_num.append(fibo(i))  # 注意这里开始调用函数,获得一个斐波那契数字,将获取到的值填充到list_num

    print(list_num)

 

 

# 最佳解法:

def fei_bo(n):

    if n <= 1:

        return (n, 0)

    else:

        (a, b) = fei_bo(n - 1)

        return (a + b, a)

 

 

print(fei_bo(5))

# 这里是线性的解法,不再重复计算前一项已知的数

 

# 求最大公约数

def maxg(m, n):

    if n == 0:

        return m

    return maxg(n, m % n)

 

 

print(maxg(6, 0))

 

# 最大公约数:

# 如果m%n=0 则n是m的最大公约数;例如4%2=0 则2是最大公约数 

# 如果m%n=K 则 n%k=?0 >>> f(m,n)=f(n,m%n)

 

 

>>>用递归实现列表排序:

def ins(li, k):

    if k == 0:

        return

    # 对前K个元素进行排序

    ins(li, k - 1)

    # 把位置K的元素插入到前面的部分

    x = li[k]

    index = k - 1

    while x < li[index]:

        li[index + 1] = li[index]

        index -= 1

    li[index + 1] = x

    print(li)

 

 

ins([1, 4, 3, 2], 3)

 

>>>需求:递归实现遍历目录

 

import os

 

 

def get_alldirfile(source_path):  # 定义一个函数获取用户输入的路径名下所有目录和文件

    if not os.path.exists(source_path):  # 判断用户输入的目录是否存在

        return  # 不存在,直接返回,结束该函数,找到一个出口

    list_name = os.listdir(source_path)  # lisdir获取所有目录,并全部放到一个列表中

    for flie_dirname in list_name:  # 遍历下所有的文件目录名

        abs_path = os.path.join(source_path, flie_dirname)  # 拼接成绝对路径

        # 判断下一级是否是目录还是文件,是文件结束,是目录继续深入,直到是文件结束

        if os.path.isfile(abs_path):  # 是文件

            print("file_path:%s" % (abs_path))

        # 也可进行复制操作,open(abs_path,"w",encoding="utf-8")

        if os.path.isdir(abs_path):

            get_alldirfile(abs_path)  # 递归函数

 

 

if __name__ == '__main__':

    path = r"F:\日语\快乐50音"

    get_alldirfile(path)

 

# 优化

import os

 

 

def file_get(file_path, n):

    list_file = os.listdir(file_path)

    for file in list_file:

        abs_file = os.path.join(file_path, file)

        if os.path.isdir(abs_file):

            print("\t" * n, file)

            file_get(abs_file, n + 1)

        else:

            print("\t" * n, file)

 

 

file_get("D:\KuGou", 1)

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

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

相关文章

laravel 项目迁移_在Laravel迁移

laravel 项目迁移Before moving forward we need to know some facts about it, 在继续前进之前&#xff0c;我们需要了解一些事实&#xff0c; Resources: In these directories, we have already a js, lang, sass and view page. Where, sass and js file holf their uncom…

Python之list对应元素求和

本次分享将讲述如何在Python中对多个list的对应元素求和&#xff0c;前提是每个list的长度一样。比如&#xff1a;a[1,2,3], b[2,3,4], c[3,4,5], 对a,b,c的对应元素求和&#xff0c;输出应为[6,9,12].    方法一&#xff1a;   直接求解&#xff0c;按照对应元素相加的…

[转载] Python中str跟int的转换

参考链接&#xff1a; Python中的类型转换 字符串str转换成int: int_value int(str_value) int转换成字符串str: str_value str(int_value) a100 b666 #int转str类型 print(int转str类型) print(int转str&#xff1a; str(a)) #str转int类型 print(str转int类型…

ot协议是什么_OT的完整形式是什么?

ot协议是什么OT&#xff1a;主题外 (OT: Off Topic) OT is an abbreviation of "Off Topic". OT是“ Off Topic”的缩写 。 It is an expression, which is commonly used in Gmail or messaging platform. It shows that the email that has been sent is irrelev…

[转载] python中字符串编码形式及其所占字节

参考链接&#xff1a; Python中的字节对象与字符串 1.常见字符串编码错误 在使用Python读文件时经常遇到编码问题引起的错误&#xff0c;比如&#xff1a; UnicodeDecodeError: gbk codec cant decode byte 0x80 in position 30: illegal multibyte sequence 遇到这种异…

[AtCoder-ARC073F]Many Moves

题目大意&#xff1a;   有一排n个格子和2枚硬币。   现在有q次任务&#xff0c;每一次要你把其中一枚硬币移到x的位置上&#xff0c;移动1格的代价是1。   两枚硬币不能同时移动&#xff0c;任务必须按次序完成。   现在告诉你两枚硬币初始状态所在的位置a和b&#xf…

ScalavsKotlin

Is Scala better that Kotlin? No..., Is Kotlin better than Scala? No... Scala比Kotlin更好吗&#xff1f; 不...&#xff0c;Kotlin胜过Scala吗&#xff1f; 没有... Both programming languages have their own profits and are for a specific set of development. It…

工业智能相机与基于PC的机器视觉的区别比较

随着科技的日渐成熟&#xff0c;机器视觉得到了飞速发展。由于嵌入式技术的发展,近几年智能相机性能显著提高&#xff0c;越来越多必须依赖于PC处理的应用开始向智能相机平台倾斜。低成本、高可靠性及易于安装维护等优势&#xff0c;使得机器视觉在制造业上的规模性应用越来越普…

[转载] python skimage在图像处理中的用法

参考链接&#xff1a; 在Python中打印单变量和多变量 基于python脚本语言开发的数字图片处理包&#xff0c;比如PIL,Pillow, opencv, scikit-image等。 PIL和Pillow只提供最基础的数字图像处理&#xff0c;功能有限&#xff1b;opencv实际上是一个c库&#xff0c;只是提供了py…

scala元组 数组_Scala中的数组

scala元组 数组Scala中的数组 (Arrays in Scala) An array is a linear data structure with a fixed number of elements. It is a collection that stores a fixed number Arrays in Scalf elements of the same datatype. In Scala, an array is 0 indexed, i.e. the first …

OpenStack —— DevStack一键自动化安装

一、DevStack介绍Devstack目前是支持Ubuntu16.04和CentOS 7&#xff0c;而且Devstack官方建议使用Ubuntu16.04&#xff0c;所以我们使用Ubuntu 16.04进行安装。默认无论是Devstack和OpenStack&#xff0c;都是采用Master的代码进行安装&#xff0c;这样经常会出现&#xff0c;今…

[转载] Python学习笔记——运维和Shell

参考链接&#xff1a; 在C / C&#xff0c;Python&#xff0c;PHP和Java中交换两个变量 目录 什么是运维 运维第一工具-shell编程 shell历史 执行脚本 基本语法 Shell脚本语法 条件测试&#xff1a;test [ if/then/elif/else/fi case/esac for/do/done …

scala java混合_Scala特性混合

scala java混合Scala | 特性混合 (Scala | Trait Mixins ) In Scala, the number of traits can be extended using a class or an abstract class. This is known as Trait Mixins. For extending, only traits, the blend of traits, class or abstract class are valid. If …

Scala铸造

Scala中的类型 (Types in Scala) Type also know as data type tells the compiler about the type of data that is used by the programmer. For example, if we initialize a value or variable as an integer the compiler will free up 4 bytes of memory space and it wi…

/ 卡路里_最大卡路里

/ 卡路里Problem statement: 问题陈述&#xff1a; Shivang is very foodie but he has a diet plan. He has an array of elements indicating the calorie of food he can consume on that day. In his diet plan, he can’t eat on for three consecutive days. But since …

[转载] Python类中的私有变量和公有变量

参考链接&#xff1a; Python中的私有变量 我们这里就直奔主题&#xff0c;不做基础铺垫&#xff0c;默认你有一些Python类的基础&#xff0c;大家在看这篇博客的时候&#xff0c;如果基础知识忘了&#xff0c;可以去菜鸟教程 从一个简单的类开始 class A(): #定义一…

OpenCV探索之路(二十五):制作简易的图像标注小工具

搞图像深度学习的童鞋一定碰过图像数据标注的东西&#xff0c;当我们训练网络时需要训练集数据&#xff0c;但在网上又没有找到自己想要的数据集&#xff0c;这时候就考虑自己制作自己的数据集了&#xff0c;这时就需要对图像进行标注。图像标注是件很枯燥又很费人力物力的一件…

固件的完整形式是什么?

FW&#xff1a;前进 (FW: Forward) FW is an abbreviation of "Forward". FW是“ Forward”的缩写 。 It is an expression, which is commonly used in Gmail or messaging platform. It is also written as FWD or Fwd or Fw. It shows that the email has been s…

[转载] python __slots__ 详解(上篇)

参考链接&#xff1a; Python的__name __(特殊变量) python中的new-style class要求继承Python中的一个内建类型&#xff0c; 一般继承object&#xff0c;也可以继承list或者dict等其他的内建类型。 在python新式类中&#xff0c;可以定义一个变量__slots__&#xff0c;它的作…

委托BegionInvoke和窗体BegionInvoke

委托BegionInvoke是指通过委托方法执行多线程任务&#xff0c;例如&#xff1a; //定义委托成员变量 delegate void dg_DeleAirport(); //指定委托函数 dg_DeleAirport dga AirportBLL.DeleteHistoryTransAirport; //通过BeginInvoke以异步线程方式执行委托函数&#xff0c;可…