python面试题总结_2019(有解释答案) --4

                                                                     

目录

84.解释一下python中pass语句的作用?

85.简述你对 input()函数的理解

86. python中的is和==

87. Python 中的作用域

88. 三元运算写法和应用场景?

89. 了解 enumerate 么?

90. 列举 5 个 Python 中的标准模块

91. 如何在函数中设置一个全局变量

92. pathlib 的用法举例

93. Python 中的异常处理,写一个简单的应用场景

94. Python 中递归的最大次数,那如何突破呢?

95. 什么是面向对象的 mro

96. isinstance 作用以及应用场景?

97. 什么是断言?应用场景?

98. lambda 表达式格式以及应用场景?

99. 新式类和旧式类的区别

100. dir()是干什么用的?

101. 一个包里有三个模块,demo1.py, demo2.py, demo3.py,但使用 from  tools import *导入模块时,如何保证只有 demo1、demo3 被导入了。

102. 列举 5 个 Python 中的异常类型以及其含义

103. copy 和 deepcopy 的区别是什么?

104. 代码中经常遇到的*args, **kwargs 含义及用法。

105. Python 中会有函数或成员变量包含单下划线前缀和结尾,和双下划线前缀结尾,区别是什么?

106. w、a+、wb 文件写入模式的区别

107. 举例 sort 和 sorted 的区别

108. 什么是负索引?

109. pprint 模块是干什么的?

110. 解释一下 Python 中的赋值运算符

111. 解释一下 Python 中的逻辑运算符

112.    讲讲 Python 中的位运算符

​113.  在 Python 中如何使用多进制数字?

114. 怎样声明多个变量并赋值?

115.  已知:

116. 用 Python 实现一个二分查找的函数

117. python 单例模式的实现方法

118. 使用 Python 实现一个斐波那契数列

119. 找出列表中的重复数字

120. 找出列表中的单个数字

121. 写一个冒泡排序

122. 写一个快速排序

123. 写一个拓扑排序

124. python 实现一个二进制计算

125. 有一组“+”和“-”符号,要求将“+”排到左边,“-”排到右边,写出具体的实现方法。

126. 单链表反转

127. 交叉链表求交点

128. 用队列实现栈

129. 找出数据流的中位数

130. 二叉搜索树中第 K 小的元素

131. 在 requests 模块中,requests.content 和 requests.text 什么区别

132. 简要写一下 lxml 模块的使用方法框架

133.说一说 scrapy 的工作流程


                                                             ****************其他内容****************


84.解释一下python中pass语句的作用?

Python pass 是空语句,是为了保持程序结构的完整性。
pass 不做任何事情,一般用做占位语句


85.简述你对 input()函数的理解


result = input('put in something please:')
print(result)
print(type(result))
input()函数接收一个标准的输入的数据,返回string类型


86. python中的is和==


Python中对象包含的三个基本要素,分别是:id(身份标识)、type(数据类型)和value(值)。
is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。
下面来看看具体区别在哪。
==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等
>>> a = 'cheesezh'
>>> b = 'cheesezh'
>>> a == b
True
is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同
>>> x = y = [4,5,6]
>>> z = [4,5,6]
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False
>>>
>>> print id(x)
>>> print id(y)
>>> print id(z)


87. Python 中的作用域


python中的作用域遵循LEGB原则:
L (Local) 局部作用域 
E (Enclosing) 闭包函数外的函数中 
G (Global) 全局作用域 
B (Built-in) 内建作用域
python按照LEGB原则搜索变量,即优先级L>E>G>B 例如:
print(type(list))        #list为   builtins
list = 1
print(list)
a = 3                #globals
def func1( ):
     a = 3            #enclosing
     def func2( ):
         a = 4        #locals
     return func2


88. 三元运算写法和应用场景?


(1)y = 99 if x > 3 else 999
(2)result = {True:1, False:2}[a>b]
(3)result = (‘FalseValue’,’TrueValue’)[a>b]
只要符合条件符合要求都可以应用吧,问的什么破问题


89. 了解 enumerate 么?


enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
例:
普通的for循环
>>>i = 0 
>>> seq = ['one', 'two', 'three'] 
>>> for element in seq: 
... print i, seq[i] 
... i +=1 
... 
0 one 
1 two 
2 three
使用enumerate的for循环
>>>seq = ['one', 'two', 'three'] 
>>> for i, element in enumerate(seq): 
... print i, element 
... 
0 one 
1 two 
2 three


90. 列举 5 个 Python 中的标准模块


time,sys,os,datetime,random, shutil, re


91. 如何在函数中设置一个全局变量


global a


92. pathlib 的用法举例


引用网址:
https://www.jianshu.com/p/a820038e65c3
from pathlib import Path
p = Path(r'd:\test\tt.txt.bk')
p.name                          # 获取文件名
p.stem                          # 获取文件名除后缀的部分
p.suffix                        # 文件后缀
p.suffixs                       # 文件的后缀们...
# ['.txt', '.bk']
p.parent                        # 相当于dirnanme
# WindowsPath('d:/test')
p.parents                       # 返回一个iterable, 包含所有父目录
# <WindowsPath.parents>
for i in p.parents:
    print(i)
# d:\test
# d:\
a.parts                         # 将路径通过分隔符分割成一个元祖
# ('d:\\', 'test', 'tt.txt.bk')
遍历文件夹
p = Path(r'd:\test')
p = Path(p, 'tt.txt')           # 字符串拼接
p.exists()                      # 判断文件是否存在
p.is_file()                     # 判断是否是文件
p.is_dir()                      # 判断是否是目录
创建文件夹
p = Path(r'd:\test\tt\dd')
p.mkdir(exist_ok=True)          # 创建文件目录(前提是tt目录存在, 否则会报错)
# 一般我会使用下面这种创建方法
p.mkdir((exist_ok=True, parents=True) # 递归创建文件目录
文件信息
p = Path(r'd:\test\tt.txt')
p.stat()                        # 获取详细信息
p.stat().st_size                # 文件大小
p.stat().st_ctime               # 创建时间
p.stat().st_mtime               # 修改时间


93. Python 中的异常处理,写一个简单的应用场景


异常处理语句try except finally
def div(a, b):
    try:
        print(a / b)
    except ZeroDivisionError:
        print("Error: b should not be 0 !!")
    else:
        print('Run into else only when everything goes well')
    finally:
        print('Always run into finally block.')
try与except只有是分支选项只有一个可以执行,没有发生异常时else语句会执行,finally总是被执行


94. Python 中递归的最大次数,那如何突破呢?


import sys
sys.setrecursionlimit(1500) # set the maximum depth as 1500
def recursion(n): 
    if(n <= 0): 
        return 
    print (n) 
    recursion(n - 1) 
if __name__ == "__main__":
    recursion(1469)
默认递归次数是1000,实际运行递归不报错大概是970左右,第二行是修改最大递归次数方法set recursion limit


95. 什么是面向对象的 mro


mro, method resolution order 方法解析顺序
https://blog.csdn.net/wangjianno2/article/details/56672442  or
https://blog.csdn.net/weixin_42104289/article/details/88528301


96. isinstance 作用以及应用场景?


用来判断一个量是否是相应的类型
print(isinstance(a,int)) #判断a是否为int类型


97. 什么是断言?应用场景?


assert断言语句用来声明某个条件是真的,
其作用是测试一个条件是否成立,如果不成立则抛出异常
例1:
assert (v1 > v2),'{0} is not bigger than {1}'.format(v1,v2)
如果v1<v2,则抛出的异常是:
AssertionError: 1 is not bigger than 2
断言跟异常的区别:
断言是用来检查非法情况而不是错误情况的,用来帮开发者快速定位问题的位置。
异常处理用于对程序发生异常情况的处理,增强程序的健壮性和容错性


98. lambda 表达式格式以及应用场景?


例1:
f = lambda x: x/2
f(6)的结果是3
例2:
fs = [(lambda x,i=i:i/x)for i in range(10)]
如果上面的式子不写i=i,而是直接写i,此处的i是首先选用全局变量的,所以如果恰好有全局变量i,就会得出其他结果,要注意;
fs[6](2)的结果是3,[ ]内是i的值,()内是x的值,这里需要说明一下,fs的type是list但是这里的list是用表达式表示的,所以有些不同,
fs[2]
Out[105]: <function __main__.<listcomp>.<lambda>>
a = fs[2]
print(a(1))
2.0
如果是fs[:](3)或者fs(3)或者fs[11]都会报错,这是lambda与for迭代结合后的一些特性


99. 新式类和旧式类的区别


新式类都从object继承,经典类不需要。
新式类的MRO(method resolution order 基类搜索顺序)算法采用C3算法广度优先搜索,而旧式类的MRO算法是采用深度优先搜索
新式类相同父类只执行一次构造函数,经典类重复执行多次。


100. dir()是干什么用的?


获得模块的属性列表


101. 一个包里有三个模块,demo1.py, demo2.py, demo3.py,但使用 from  tools import *导入模块时,如何保证只有 demo1、demo3 被导入了。


增加__init__.py文件,并在文件中增加:__all__ = ['mod1','mod3']


102. 列举 5 个 Python 中的异常类型以及其含义


AttributeError      试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError          输入/输出异常;基本上是无法打开文件
ImportError      无法引入模块或包;基本上是路径问题或名称错误
IndentationError    语法错误(的子类) ;代码没有正确对齐
IndexError      下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError          试图访问字典里不存在的键
KeyboardInterrupt       Ctrl+C被按下
NameError      使用一个还未被赋予对象的变量
SyntaxError      Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError      传入对象类型与要求的不符合
UnboundLocalError    试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError      传入一个调用者不期望的值,即使值的类型是正确的


103. copy 和 deepcopy 的区别是什么?


拷贝之前再说下 b =a,这种情况两者的id是一个
[[], []] 列表的嵌套, [{}, {}] 字典的嵌套,可变类型嵌套了可变类型, 浅拷贝只拷贝最外层,会生成新的对象, 内层是引用, 深拷贝外层和内层都会进行拷贝,都是全新的对象, 都有独立的存储空间

In [22]: a = [11, 22]
In [23]: b = [33, 44] 
In [24]: c = [a, b]
In [25]: d = copy.copy(c)
In [26]: e = copy.deepcopy(c)
 
In [27]: id(c)
Out[27]: 2644923219336
In [28]: id(d)
Out[28]: 2644923160392
In [29]: id(e)
Out[29]: 2644923143624
In [30]: id(a)
Out[30]: 2644913732296
In [32]: id(d[0])
Out[32]: 2644913732296
In [33]: id(e[0])
Out[33]: 2644923077512


104. 代码中经常遇到的*args, **kwargs 含义及用法。


https://blog.csdn.net/lcxxcl_1234/article/details/80726668
*args和**kwargs主要用于函数定义。可以将不定数量的参数传递给某个函数
*args是用来发送一个非键值对的可变数量的参数列表给一个函数
 
**kwargs允许你将不定长度的键值对作为参数传递给一个函数。如果你想要在一个函数里处理带名字的参数,你应该使用**kwargs
 
其实关键是*与**,而args与kwargs换成其他也可以,只不过是一种常见的写法


105. Python 中会有函数或成员变量包含单下划线前缀和结尾,和双下划线前缀结尾,区别是什么?


_xxx
单下划线开头的变量,表明这是一个受保护(protected)的变量,原则上不允许直接访问
但是外部类还是可以访问到这个变量。
 
__xxx
双下划线开头的,表示的是私有类型(private)的变量,只能允许这个类本身进行访问,甚至它的子类也不可以,用于命名一个类属性(类变量),调用时名字会被改变
可以通过dir(sd)查看变量,通过python的私有变量碾压特性,sd.__name变成了sd._Student__name。Python把以两个或以上下划线字符开头且没有以两个或以上下划线结尾的变量当作私有变量。私有变量会在代码生成之前被转换为长格式(变为公有)。转换机制是这样的:在变量前端插入类名,再在前端加入一个下划线字符。这就是所谓的私有变量碾压(Private name mangling)
 
__xxx__
以双下划线开头,并且以双下划线结尾的,是内置变量,内置变量是可以直接访问的,如__init__,__import__或是__file__。所以,不要自己定义这类变量。
添加个进阶的链接:
https://www.cnblogs.com/hester/articles/4936603.html


106. w、a+、wb 文件写入模式的区别


w:只写模式,文件不存在则新建文件,文件指针在文件开头,会清空原来的文件内容
a+:读写模式,文件不存在新建文件,文件指针位于文件结尾,不会清空原来文件内容,可在任意位置读取,但只能在文件末尾写入
wb:与w的区别是,wb打开的是二进制模式,w打开的是文本模式,所有带‘b’的都是二进制模式打开


107. 举例 sort 和 sorted 的区别


使用sort()方法对list排序会修改list本身,不会返回新list,sort()不能对dict字典进行排序;
sorted方法对可迭代的序列排序生成新的序列,对dict排序默认会按照dict的key值进行排序,最后返回的结果是一个对key值排序好的list;
python2.4开始,list.sort()与sorted()增加了key参数,具体用法请自查


108. 什么是负索引?


负索引就是像a[-1],表示从末尾向前数的第一个


109. pprint 模块是干什么的?


pprint是打印模块,与print的区别是pprint打印出来的数据结构更加完整;
所谓的完整一般就是分行打印,每行一个数据结构,方便阅读;


110. 解释一下 Python 中的赋值运算符


 

111. 解释一下 Python 中的逻辑运算符


112.    讲讲 Python 中的位运算符



113.  在 Python 中如何使用多进制数字?


二进制:0bxxxx,
转为二进制:bin(xxx)
八进制:0oxxxx,
转为八进制:oct(xxx)
十进制:xxxx,
转为十进制:dec(xxx)
十六进制:0fxxxx,
转为十六进制:hex(xxx)


114. 怎样声明多个变量并赋值?


多个变量赋值:
a,b = 1,2
多个变量声明并赋值:
for i in range(10):
    cmd = "var_%s = i" % i
    exec (cmd)
#eval("var_%s" % i)
print (var_5)
结果:5
                                                               

                                                                  ****************算法和数据结构****************


115.  已知:


AList = [1,2,3]
BSet = {1,2,3}
(1)    从 AList和BSet中查找4,最坏时间复杂度那个大?
(2)    从 AList和BSet中插入4,最坏时间复杂度那个大?
需要弄清楚列表与哈希表的区别:
对于查找,列表的时间复杂度是O(n), set是O(1)
对于插入,两个都是O(1)
可以关注下链接,讲的python数据结构与算法,很不错
https://www.cnblogs.com/pengsixiong/p/5304065.html


116. 用 Python 实现一个二分查找的函数


def dichotomy_search(list_f,target_d):
    start = 0
    end = len(list_f)-1
    find_state = False
    while start <= end and not find_state:
        midpoint = (start+end)//2
        #print(midpoint)
        if list_f[midpoint] < target_d:
            start = midpoint + 1
        elif list_f[midpoint] > target_d:
            end = midpoint - 1
        else:
            find_state = True
    return (find_state,midpoint)
list_f = [1,2,3,4,5,6,7,8,9,11,23,45]
#target_d = 8
result = dichotomy_search(list_f,3)
print(result)


117. python 单例模式的实现方法


单例模式就是一个类只能创建一个实例化,创建的所有实例化的id都是相同的
单例模式实现有两种方式,
1.    使用__metaclass__元类来实现
class Singleton(type):    
    def __init__(cls, name, bases, dict):    
        super(Singleton, cls).__init__(name, bases, dict)    
        cls._instance = None    
    def __call__(cls, *args, **kw):    
        if cls._instance is None:    
            cls._instance = super(Singleton, cls).__call__(*args, **kw)    
        return cls._instance    
class MyClass(metaclass= Singleton):  
    def __init__(self,name):
        self.name = name
a = MyClass('')
print(a)
b = MyClass('')
print(b)

2.使用装饰器(decorator)
def singleton(cls, *args, **kw):    
    instances = {}    
    def _singleton():    
        if cls not in instances:    
            instances[cls] = cls(*args, **kw)    
        return instances[cls]    
    return _singleton    
@singleton    
class MyClass(object):    
    a = 1    
    def __init__(self, x=0):    
        self.x = x     

3.使用模块
Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了
class Singleton(object):
    def foo(self):
        pass
singleton = Singleton()
保存为mysingleton.py文件
form * import singleton 这样就ok了
这是比较简单易实现的方法还有其他比如类方法等等


118. 使用 Python 实现一个斐波那契数列


1.用递归方式打印第n项
def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return(1)
    elif n == 2:
        return(1)
    else:
        return(fibonacci(n-1)+fibonacci(n-2))
print(fibonacci(10))
2.常规方法打印前n项数列
def fibonacci(n):
    list_f = [0,1]
    if n > 1:
        for i in range(n-1):
            list_f.append(list_f[i]+list_f[i+1])   
    return(list_f[:n])        
print(fibonacci(10))


119. 找出列表中的重复数字


1.用count计数
mylist = [1,2,2,2,2,3,3,3,4,4,4,4]
myset = set(mylist)
for item in myset:
print("the %d has found %d" %(item,mylist.count(item)))
2.
from collections import Counter
result = Counter([1,2,2,2,2,3,3,3,4,4,4,4])
print(result)
需要说明,结果是dict,输出的结果是Counter({2: 4, 4: 4, 3: 3, 1: 1})


120. 找出列表中的单个数字


在119的1基础上稍微修改就可以


121. 写一个冒泡排序


list_f = [12,32,31,52,17,6,19,10]
def bubble_sort(list_f):
    length_list = len(list_f)
    while(length_list>1):
        for i in range(length_list-1):
            if list_f[i] > list_f[i+1]:
                inmed_var = list_f[i]
                list_f[i] = list_f[i+1]
                list_f[i+1] = inmed_var
        length_list = length_list-1
        print(length_list)
    return list_f
print(bubble_sort(list_f))


122. 写一个快速排序


快速排序常用且重要,这里总结出3种排序方式:
1.表达式方式
array = [2,5,6,1,2,89,34,21,3]
quick_sort = (
            lambda array: array if len(array) <= 1 else
            quick_sort([item for item in array[1:] if item <= array[0]]) 
            + [array[0]] 
            + quick_sort([item for item in array[1:] if item > array[0]])
            )
print(quick_sort(array))
通过一个表达式完成,有两点说明:
长表达式换行有两种方式一个是( ) or [ ] or { },另一种就是在想要换行的位置加’\’
另一个是,用lambda实现递归时,公式中的递归quick_sort( )括号内的内容是在当前执行出结果然后将list给递归函数,换句话说就是quick_sort([item for item in array[1:] if item <= array[0]])这个公式,递归时quick_sort(list),是这种模式,然后list是[item for item in array[1:] if item <= array[0]]的运行后的结果。
2.一般思路的块排
array = [2,5,6,1,2,89,34,21,3]
def quick_sort(array, left, right):
    if left >= right:
        return
    low = left
    high = right
    key = array[low]
    while left < right:
        while left < right and array[right] > key:
            right -= 1
        array[left] = array[right]
        while left < right and array[left] <= key:
            left += 1
        array[right] = array[left]
    array[right] = key
    quick_sort(array, low, left - 1)
    quick_sort(array, left + 1, high)
quick_sort(array,0,8)
print(array)
感觉还是比较绕的,多在纸上写一下推到一下可能会更容易理解;
3.这种方法相对简洁一些
array = [2,5,6,1,12,89,34,21,3]
def quick_sort(array, l, r):
    if l < r:
        q = partition(array, l, r)
        quick_sort(array, l, q - 1)
        quick_sort(array, q + 1, r)
def partition(array, l, r):
    x = array[r]
    i = l - 1
    for j in range(l, r):
        if array[j] <= x:
            i += 1
            array[i], array[j] = array[j], array[i]
    array[i + 1], array[r] = array[r], array[i+1]
    return i + 1
quick_sort(array,0,len(array)-1)
print(array)
4.用栈的方式实现非递归的快排程序
array = [2,5,6,1,12,89,34,21,3]
def quick_sort(array, l, r):
    if l >= r:
        return
    stack = [ ]
    stack.append(l)
    stack.append(r)
    print(stack)
    while stack:
        low = stack.pop(0)
        high = stack.pop(0)
        if high - low <= 0:
            continue
        x = array[high]
        i = low - 1
        for j in range(low, high):
            if array[j] <= x:
                i += 1
                array[i], array[j] = array[j], array[i]
        array[i + 1], array[high] = array[high], array[i + 1]
        stack.extend([low, i, i + 2, high])
        print(stack)
quick_sort(array,0,len(array)-1)
print(array)
快排的几种实现方式都不是很好理解


123. 写一个拓扑排序


def toposort(graph):
    in_degrees = dict((u,0) for u in graph)   #初始化所有顶点入度为0
    vertex_num = len(in_degrees)
    for u in graph:
        for v in graph[u]:
            in_degrees[v] += 1       #计算每个顶点的入度
    Q = [u for u in in_degrees if in_degrees[u] == 0]   # 筛选入度为0的顶点
    Seq = []
    while Q:
        u = Q.pop()       #默认从最后一个删除
        Seq.append(u)
        for v in graph[u]:
            in_degrees[v] -= 1       #移除其所有指向
            if in_degrees[v] == 0:
                Q.append(v)          #再次筛选入度为0的顶点
    if len(Seq) == vertex_num:       #如果循环结束后存在非0入度的顶点说明图中有环,不存在拓扑排序
        return Seq
    else:
        print("there's a circle.")
G = {'a':'bce','b':'d','c':'bd','d':'','e':'cd'}
print(toposort(G))


124. python 实现一个二进制计算


这个题目的真正目的我没有太理解,
如果理解成二进制的转化,bin( )也可以直接完成,不过这里需要注意的是,type(bin())是str,如果str进行加法,是将两个字符串拼接,并不是我们想要的计算
如果c = 0b11011,type(c)是intpython是没有二进制这个数据格式的,如果要实现只能转化成int计算后转回二进制形式
如果非要代码的形式实现二进制的+-*/,可能会繁琐一点,这里略


125. 有一组“+”和“-”符号,要求将“+”排到左边,“-”排到右边,写出具体的实现方法。


target = '+--++++--'
result1 = []
result2 = []
for i in target:
    if i == '+':
        result1.append(i)
    else:
        result2.append(i)
result1.extend(result2)
print(result1)
print(('').join(result1))


126. 单链表反转


class Node(object):
    def __init__(self, data, next=None):
        self.val = data
        self.next = next

def fun4(head):
    if head == None:
        return None
    L,M,R = None,None,head
    while R.next != None:
        L = M
        M = R
        R = R.next
        M.next = L
    R.next = M
    return R
#测试用例
if __name__ == '__main__':
    l1 = Node(3)
    l1.next = Node(2)
    l1.next.next = Node(1)
    l1.next.next.next = Node(9)
    l = fun4(l1)
    print (l.val, l.next.val, l.next.next.val, l.next.next.next.val)


127. 交叉链表求交点


class ListNode:
    def init(self, x):
        self.val = x
        self.next = None
    def node(l1, l2):
        length1, length2 = 0, 0
        # 求两个链表长度
        while l1.next:
            l1 = l1.next
            length1 += 1
        while l2.next:
            l2 = l2.next
            length2 += 1
        # 长的链表先走
        if length1 > length2:
            for _ in range(length1 - length2):
                l1 = l1.next
        else:
            for _ in range(length2 - length1):
                l2 = l2.next
        while l1 and l2:
            if l1.next == l2.next:
                return l1.next
            else:
                l1 = l1.next
                l2 = l2.next


128. 用队列实现栈


队列是先进先出,栈是先进后出,如果非要把队列当栈来实现的话,如下:
from collections import deque
queue = deque(["a"])
queue.append("b")
queue.append("c")
for _ in range(3):                                
print(queue.pop())
如果是queue.popleft( )的话,就符合先进先出的特性了;这个功能的实现其实是导入了tensorflow的包,算是钻了个空子吧。


129. 找出数据流的中位数


import heapq
class BigHeap():
    def __init__(self):
        self.arr = list()
    def heap_insert(self, val):
        heapq.heappush(self.arr, -val)
    def heapify(self):
        heapq.heapify(self.arr)
    def heap_pop(self):
        return -heapq.heappop(self.arr)
    def get_top(self):
        if not self.arr:
            return
        return -self.arr[0]
class SmallHeap():
    def __init__(self):
        self.arr = list()
    def heap_insert(self, val):
        heapq.heappush(self.arr, val)
    def heapify(self):
        heapq.heapify(self.arr)
    def heap_pop(self):
        return heapq.heappop(self.arr)
    def get_top(self):
        if not self.arr:
            return
        return self.arr[0]
class MedianHolder():
    def __init__(self):
        self.bigHeap = BigHeap()
        self.smallHeap = SmallHeap()
    def addNum(self, num):
        if len(self.bigHeap.arr) == 0:
            self.bigHeap.heap_insert(num)
            return
        if self.bigHeap.get_top() >= num:
            self.bigHeap.heap_insert(num)
        else:
            if len(self.smallHeap.arr) == 0:
                self.smallHeap.heap_insert(num)
                return
            if self.smallHeap.get_top() > num:
                self.bigHeap.heap_insert(num)
            else:
                self.smallHeap.heap_insert(num)
        self.modifyTwoHeapSize()
    def getMedian(self):
        smallHeapSize = len(self.smallHeap.arr)
        bigHeapSize = len(self.bigHeap.arr)
        if smallHeapSize + bigHeapSize == 0:
            return None
        smallHeapHead = self.smallHeap.get_top()
        bigHeapHead = self.bigHeap.get_top()
        if (smallHeapSize + bigHeapSize) %2 == 0:
            return (smallHeapHead+bigHeapHead)/2
        else:
            return smallHeapHead if smallHeapSize > bigHeapSize else bigHeapHead
    def modifyTwoHeapSize(self):
        smallHeapSize = len(self.smallHeap.arr)
        bigHeapSize = len(self.bigHeap.arr)
        if smallHeapSize == bigHeapSize + 2:
            self.bigHeap.heap_insert(self.smallHeap.heap_pop())
        if bigHeapSize == smallHeapSize + 2:
            self.smallHeap.heap_insert(self.bigHeap.heap_pop())
if __name__ == '__main__':
    arr = [68,51,42,92,13,46,24,58,62,72,32]
    medianHold = MedianHolder()
    for i in range(len(arr)):
        medianHold.addNum(arr[i])
        print(medianHold.getMedian())
关于heapq的说明见以下链接:
https://rookiefly.cn/detail/225


130. 二叉搜索树中第 K 小的元素


1.递归
class Solution(object):
    def kthSmallest(self, root, k):
        self.count=k
        self.res=0
        def core(root):
            if  root :
                core(root.left)
                self.count=self.count-1
                if self.count==0:
                    self.res=root.val 
                core(root.right)
        core(root)
        return self.res
2.循环
class Solution(object):
    def kthSmallest(self, root, k):
        stack=[]
        while True:
            if root:
                stack.append(root)
                root=root.left
            else:
                root=stack.pop()
                k=k-1
                if k==0:
                    return root.val
                else:
                    root=root.right

                                                             ****************爬虫问题****************


131. 在 requests 模块中,requests.content 和 requests.text 什么区别


可以参考这个链接:
https://blog.csdn.net/xie_0723/article/details/51361006
内容概括如下
区别总结就是:
requests.text返回的是Unicode型的数据。
requests.content返回的是bytes型也就是二进制的数据
操作方式就是,如果想取得文本就用.text,如果想获取图片,就用.content
给个例子:
import requests
jpg_url = 'http://img2.niutuku.com/1312/0804/0804-niutuku.com-27840.jpg'
content = requests.get(jpg_url).content
with open('demo.jpg', 'wb') as fp:
    fp.write(content)


132. 简要写一下 lxml 模块的使用方法框架


lxml是处理网页数据的第三方库,用Cython实现。
细节参考链接:
https://www.cnblogs.com/ospider/p/5911339.html


133.说一说 scrapy 的工作流程


1.首先Spiders(爬虫)将需要发送请求的url(requests)经ScrapyEngine(引擎)交给Scheduler(调度器)。
2.Scheduler(排序,入队)处理后,经ScrapyEngine,DownloaderMiddlewares(可选,主要有User_Agent, Proxy代理)交给Downloader。
3.Downloader向互联网发送请求,并接收下载响应(response)。将响应(response)经ScrapyEngine,SpiderMiddlewares(可选)交给Spiders。     
4.Spiders处理response,提取数据并将数据经ScrapyEngine交给ItemPipeline保存(可以是本地,可以是数据库)。
5.提取url重新经ScrapyEngine交给Scheduler进行下一个循环。直到无Url请求程序停止结束
https://blog.csdn.net/miner_zhu/article/details/81094077
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值