zoukankan      html  css  js  c++  java
  • python面试_总结01_概念和内置高阶函数

    - 简答题

    1、请谈谈Python中is 和 == 的区别(代码演示)

    is用于比较两个变量是否引用了同一个内存地址,is表示的是对象标识符(object identity),作用是用来检查对象的标识符是否一致,也就是比较两个对象在内存中的地址是否一样。

    ==用于比较两个变量的值是否相等,==表示的是相等(equality)。

    is是检查两个对象是否指向同一块内存地址,而==是检查他们的值是否相等。

    可以看出,is是比==更严格的检查,is返回True表明两个对象指向同一块内存,值也一定相同。

    # case 1:对于数值型和字符串型对象, python的存储机制使得a和b其实指向同一个地址,所以is和==都是True
    a = 7
    b = 7
    print("a和b是int型")
    print("a的地址是", id(a))
    print("b的地址是", id(b))
    # 比较地址
    print("a和b的地址值相同?", a is b)
    # 比较值
    print("a和b的数值相同?", a == b)
    a和b是int型
    a的地址是 139947890484128
    b的地址是 139947890484128
    a和b的地址值相同? True
    a和b的数值相同? True
    # case 2:对于list、tuple等容器,a和b虽然内容一样,但是是两个不同的对象引用,指向两个不同的内存地址
    a = [1, 2, 3]
    b = [1, 2, 3]
    print("a和b是列表")
    print("a的地址是", id(a))
    print("b的地址是", id(b))
    # 比较地址
    print("a和b的地址值相同?", a is b)
    # 比较值
    print("a和b的数值相同?", a == b)
    print("*"*20)
    
    a = (1, 2, 3)
    b = (1, 2, 3)
    print("a和b是元组")
    print("a的地址是", id(a))
    print("b的地址是", id(b))
    # 比较地址
    print("a和b的地址值相同?", a is b)
    # 比较值
    print("a和b的数值相同?", a == b)
    a和b是列表
    a的地址是 139947465543432
    b的地址是 139947786638728
    a和b的地址值相同? False
    a和b的数值相同? True
    ********************
    a和b是元组
    a的地址是 139947474361656
    b的地址是 139947474360072
    a和b的地址值相同? False
    a和b的数值相同? True
    # case 3:实际上可以通过修改对象的__eq__方法改变==的比较方式
    # 对象相等的判断
    # python中的对象是否相等有两个层面,
    # 一个层面是是否是同一个对象,及在内存中是否共用一个内存区域,用is判断,另一个是对象的值是否相等,用==判断。
    
    # 比较两个python对象是否相等,看个例子:
    class student(object):
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
        def __eq__(self, *args, **kwargs):
            return object.__eq__(self, *args, **kwargs)
    like = student("like", 25, "male")
    xue = student("xue", 23, "female")
    dong = student("like", 25, "male")
    print(like is xue) # False
    print(like is dong) # False
    print(like == dong) # False
    # 这里有两个student类的实例化对象,like和xue很明显是两个不同的对象,他们的不同体现在所占内存地址不同且对象的属性也不同。
    
    # ************************************************************************
    # like和dong虽然属性相同,但是is和==两种判断的结果也都为false,
    # 在实际情况中,我们大多都希望like和dong属性相同,就认为是同一个对象,所以我们需要重写类的eq方法:
    class student(object):
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
        def __eq__(self,other):
            return self.__dict__ == other.__dict__
    #     return self.name == other.name
    like = student("like",25,"male")
    dong = student("like",25,"male")
    print(like == dong) # True
    # 调用一个对象的dict方法可以用字典的形式输出其属性列表,由于两个对象的属性相同,所以==运算为True。
    
    # ************************************************************************
    # 自定义python对象相等的条件
    # 当然在实际情况下,可以更灵活的定义两个对象相等的条件,比如名字一样就认为相等。
    class student(object):
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
        def __eq__(self,other):
            return self.name == other.name
    like = student("like", 25, "male")
    dong = student("like", 23, "female")    
    print(like == dong) # True
    
    # ************************************************************************
    # 在实际应用中,有一个场景是处理对象是否在list里,不在就加入。
    like = student("like", 25, "male")
    dong = student("like", 25, "male")
    list1 = []
    list1.append(like)
    if dong not in list1:
        list1.append(dong)
    print(len(list1)) # 1
    False
    False
    False
    True
    True
    1

    2、Python中的高阶函数是指什么

    map、reduce、filter、zip这类函数

    2.1、map()

    map() 顾名思义,map函数的作用是映射。python源码解释如下:

    map(func, *iterables) --> map object

    Make an iterator that computes the function using arguments from each of the iterables. Stops when the shortest iterable is exhausted.

    简单来说,

    map()它接收一个函数 f 和一个可迭代对象(这里理解成 list),并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

    注意:map()函数不改变原有的 list,而是返回一个新的 list。

    # 举例:
    _list = [1, 2, 3]
    
    def f(x):
        return x * x
    # map(f, _list)  # map at 0x7f43e045dba8>
    print(list(map(f, _list)))  # 通过map,完成了对列表每个元素开平方的功能
    
    # 结合匿名函数使用,实现功能同上
    print(list(map(lambda x: x * x, _list)))
    
    # 任务
    # 假设用户输入的英文名字不规范,没有按照首字母大写,后续字母小写的规则,
    # 请利用map()函数,把一个list(包含若干不规范的英文名字)变成一个包含规范英文名字的list:
    list_ = ['lll', 'lKK', 'wXy']
    def f_(abc):
        '''
        首字母大写,后续字母小写
        '''
        return abc[0:1].upper() + abc[1:].lower()
    #     return abc.capitalize()
    print(list(map(f_, list_)))
    [1, 4, 9]
    [1, 4, 9]
    ['Lll', 'Lkk', 'Wxy']

    2.2、reduce()

    reduce()和map()类似,但是reduce()传入的函数 f 必须接收两个参数,而且reduce()还要导包。。。差评

    # 举例
    from functools import reduce
    ## 累加求和,小学经典的求前100个数的问题。。。
    def add(x, y):
        return x + y
    
    print(reduce(add, [i for i in range(1, 101)]))
    
    # 匿名函数实现同样功能
    print(reduce(lambda x, y: x + y, [i for i in range(1, 101)]))
    5050
    5050

    2.3、filter()

    顾名思义,过滤用的函数,用法同map()类似,filter()函数接收一个函数 f 和一个list,只不过这里的f起到的是判断的作用,符合条件的留下,不符合的丢掉

    # 举例
    # 过滤列表中所有能被3乘除的数和等于2的数
    list_ = [-9, -7, -6, 0, 2, 16, 99]
    def f(x):
        if x % 3 == 0:
            return x  # 非0即真,这里的0认为是false,无法被选中
        elif x == 2:  # x == 0。。。抑郁了
            return x
        
    # filter(f, list_) # <filter at 0x7f43e0308b70>
    list(filter(f, list_))
    [-9, -6, 2, 99]

    2.4、zip()

    zip函数接受任意多个可迭代对象作为参数,将对象中对应的元素打包成一个tuple,然后返回一个可迭代的zip对象

    # 举例
    a1=[1,2,3]
    a2=[4,5,6]
    a3=[7,8,9]
    a4=["a","b","c","d"]
    
    zip1 = zip(a1,a2,a3)
    print(zip1)  # <zip object at 0x7f43e03def08>
    # print(list(zip1))  # 这里变成list的话,直接输出[(1, 4, 7), (2, 5, 8), (3, 6, 9)],下面的for循环就没有输出了
    
    print("*"*20)
    for i in zip1:
        print(i)
    print("*"*20)
    
    # 这个可迭代对象可以使用循环的方式列出其元素
    # 若多个可迭代对象的长度不一致,则所返回的列表与长度最短的可迭代对象相同.
    zip2 = zip(a1, a4)
    # print(list(zip2))
    for i in zip2:
        print(i)
    <zip object at 0x7f480ef99788>
    ********************
    (1, 4, 7)
    (2, 5, 8)
    (3, 6, 9)
    ********************
    (1, 'a')
    (2, 'b')
    (3, 'c')

    3、Python类中有哪些的成员,如何分类他们,他们各自又有哪些用途?

    python是一种以面向对象为思想的编程语言,面向对象的核心在于,一切皆对象,而对象由两部分组成,属性 + 方法
    python类中包括了类属性(即类变量)、类方法、成员属性(实例属性)、成员函数(实例方法)、静态方法
    比如我们构建动物类 class Animal,这个Animal类可以有体重,颜色等类属性,当实例化Animal类的实例对象时,
    这些类属性是共用的(实例对象共用),同理类方法也是这个意思。而Animal类在构建的时候有一种魔法方法成为构造方法,"_init_",
    它会在实例化对象的时候给每个对象初始化不同的实例属性,这个是每个成员独有的。
    而在Animal类其中所写的任何(不加装饰器)类似python函数(def开头的...)的方法都是实例方法,他们是类实例化对象所共有的方法
    对于类方法和静态方法,都是在def前面加上装饰器(@classmethod和@staticmethod),类方法即类和对象都可以用,
    静态方法类似于普通函数,不仅该类和对象共用静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,
    也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。

    4、Python中列表,元组的相同之处及区别都有哪些?集合与字典呢?

    列表、元组、集合、字典都是python中的容器,可以存大量单独的int,str等数据。
    列表和元组相同点:1、有序,2、都是一种序列,3、都是可迭代对象,都支持索引切片等操作
    不同点:列表是可变数据类型,元组是不可变数据类型
    集合和字典相同点:都是无序的
    不同点:1、集合中不存重复相同的元素,2、字典中所存的元素都是键值对一一对应的,是以哈希表为基础的映射关系


















































  • 相关阅读:
    1scala基础
    3scala高级
    03spark kafka
    01spark基础
    04spark streaming
    2scala集合
    02spark sql
    学习java程序设计环境的心得
    第五章继承
    第二周学习Java心得
  • 原文地址:https://www.cnblogs.com/kongweisi/p/12095677.html
Copyright © 2011-2022 走看看