zoukankan      html  css  js  c++  java
  • python面试题(一)

    整理了一些python面试可能遇到的题,提供给大家,希望能对大家有用!

    1.下面的代码会输出什么?

    def extend_list(val, list=[]):
        list.append(val)
        return list
    
    list1 = extend_list(10)
    list2 = extend_list(123,[])
    list3 = extend_list('a')
    
    print(list1)
    print(list2)
    print(list3)

    extend_list函数有两个参数,val和默认参数list,返回值为list

    如果你认为输出的值为:[10],[123],[a];那你就上当了,这正是出题者想让你犯的错误。

    正确答案是:[10, a],[123],[10, a];为什么呢?

    关键点就在extend_list返回的值,它返回的是一个变量,绑定在一个固定的地址,list3传参之后改变了list,所以最后打印的时候,list1和list3的值相同。

    那么为什么list2没变呢?因为list2传参的时候给传入了一个空的列表,list2所对应的list所绑定的地址发生了改变。

    如果这样说你还不清楚的话,那么我借助代码来看一看。

    def extend_list(val, list=[]):
        list.append(val)
        return list
    
    
    list1 = extend_list(10)
    print(list1)  # [10]
    print(id(list1))  # 140427568644424
    list2 = extend_list(123, [])
    print(list2)  # [123]
    print(id(list2))  # 140427568644360
    list3 = extend_list('a')
    print(list3)  # [10, 'a']
    print(id(list3))  # 140427568644424
    
    
    print(list1)  # [10, 'a']
    print(list2)  # [123]
    print(list3)  # [10, 'a']

    id(变量名) 可以查询变量所绑定的地址。

    2.有一数组,从左到右渐增,从上到下渐增,给一个数字,判断它是否在这个数组中。

     arr = [[1,4,7,10,15], [2,5,8,12,19], [3,6,9,16,22],
      [10,13,14,17,24], [18,21,23,26,30]]
    
    def getNum(num, data=None):
        while data:
            #  当data不为空,如果num大于data数组第1个元素的最后一项
            #  删除此元素,再执行此比较
            if num > data[0][-1]:
                del data[0]
                getNum(num, data=None)
            #  如果num小于此时的data数组第一个元素的最后一项
            #  那么利用zip转换矩阵,将所有元素的最后一项都删除掉
            #  然后再次用zip还原数组,回到第一步再次开始比较
            elif num < data[0][-1]:
                data = list(zip(*data))
                del data[-1]
                data = list(zip(*data))
                getNum(num, data=None)
            #  如果num不大于也不小于此时data数组第一个元素的最后一项
            #  那么num就是这一项,返回True
            else:
                return True
        #  当data为空时,num已经和原data数组比较完毕,且没有找到相同的数字
        #  返回False
        return False
    
    #  如果是在当前文本打开,则执行print
    if __name__ == '__main__':
        print(getNum(18, arr))

    3.求两个数的最大公约数、最小公倍数。

    这个是送分题,我们可以用最笨的办法

    def maxCommon(a, b):
      # 两数的最大公因数最大为较小的数,所以我们遍历从1到较小的数
    for i in range (1, b+1):
        # 如果a和b除以i余数都为0,那么i就是a和b的公因数
    if a % i == 0 and b % i == 0:
          # 将i赋值给变量mx,因为i会从1到b,所以只要满足条件的i,都会对mx赋值
          # 新值会替代旧值,所以最后返回的是最大公因数
          mx
    = i return mx


    print(maxCommon(36, 21)) # 3

    这种笨办法我们称之为“穷举法”,既然有笨办法,那就有聪明的办法!

    接下来我们就来看聪名的办法:欧几里得算法(碾转相除法),叫欧几里得算法显得高大上,碾转相除法贴切的多。

    def modUntil(a, b):
        while b:
        # 循环,序列赋值 a, b
    = b, a%b return a print(modUntil(36, 21)) # 3

    这是什么鬼?代码怎么可以这么简洁?怎么就循环一直除一直除就可以得到最大公因数了?还除的是余数?

    容老夫给你娓娓道来。

    假设x,y有一最大公因数z,x和y都可以被z整除,那么对任意整数m和n,mx+ny也可以被z整除。

    现在有x / y = q 余数为 w,那么x = qy + w,可知 x -qy = w,结合上一行可知 w 可以被z整除,也就是说,x除以y的余数可以被他俩的最大公因数整除。

    循环到最后,a的值为上一循环时的余数,b的值为0。

    是不是涨见识了?在欧几里得算法的基础上,有没有受到启发,有没有想到其它算法?

    不吹不黑,我没想到,你如果想到了,那么你牛笔了。。。。

    我们再来看下一种算法:尼考曼彻斯法(碾转相减法、更相减损术),如果你想到的也是这种算法,那么恭喜你,你的思维可以和尼考曼彻斯比肩了。

    def deUntil(a, b):
        while a != b:
            if a > b:
                a = a - b
            else:
                b = b - a
        return b

    不会又一脸懵逼了吧?碾转相除的道理还记得吗?两者一个道理,既然能除就能减,多减几次,剩下的等同于余数。。。

    最大公约数的算法会了,那么最小公倍数就简单了

    将两个数相乘再除以最大公约数就是最小公倍数,这里就不做演示了。

  • 相关阅读:
    近似与精确——《狂人C》习题解答15(第三章习题5)
    策略、次序和测试—《狂人C》习题解答16(第三章习题6)
    华丽的递归——将正整数表示为平方数之和
    Horner's rule——《狂人C》习题解答5(第二章习题8)
    .NET牛人需要了解的问题[转]
    Ajax的一个封装[原创]
    公司项目改进之权限篇[原创]
    【方案解决】ncelab: *E,CUIOCP Outofmodule reference terminating in a VHDL scope is not allowed
    【原创】关于setup和hold的深入浅出【Verilog】
    LEC3南京大学操作系统重点简答题素材中断处理
  • 原文地址:https://www.cnblogs.com/jiangchunyu/p/9806833.html
Copyright © 2011-2022 走看看