串讲-Python基础练习
-
Python 是一个解释型的脚本语言,运行速度慢,代码简洁,学习时间短,开发速度快
-
Java 编译型语言,运行速度适中,开发效率适中,目前最流行的语言
-
c/c++ 现存的编程语言的老祖,执行速度最快,代码复杂,开发难度大
-
go 编程界的小鲜肉,高并发能力最高,代码像Python一样简洁,运行速度和c一样快
-
列举Python2和Python3的区别
-
Python2:
-
源码不统一,源码重复
-
input接受到的是数据本身
-
整除返回的是整数(向下取整)
-
打印range(10) 是一个列表,内容是[0-9]
-
整形型,长整型
-
默认编码是ascll,不支持中文名
-
-
Python3:
-
源码统一,源码不重复
-
input接收到的是字符串
-
整除返回的是浮点数(小数)
-
打印range(10)就是本身
-
全是整型
-
默认编码是Unicode,支持中文
-
-
-
看代码写结果
-
1
-
0
-
-
比较下值有啥不同
-
v1和v2都是一个列表里面有3个元素
-
v3是一个列表里面有三个元租
-
-
a,b=b,a
-
引号的区别
-
单引号和双引号基本没什么区别,有时需要单引号里面套双引号或双引号套单引号
-
三引号是多行注释,注释的代码不会执行
-
三引号也可以是多行代码,会按照原始代码输出
-
-
is和==的区别
-
is 表示判断对象的id是否相同
-
== 表示判断对象的值是否相同
-
-
tuple和list的转化
-
tuple-->list list(tuple)
-
list -->tuple tuple(list)
-
-
s=s[::-1]
-
..
-
交集 s&s1
-
并集 s|s1
-
差集 s-s1
-
-
x,y不是int数据类型
-
Python中如何拷贝一个对象
-
复制
-
深浅拷贝
-
-
赋值,深浅拷贝的区别
-
赋值,相当于给一个东西起了两个名字
-
浅拷贝 只拷贝第一层元素,只修改第一层不可变数据的时候不进行改变,给可变数据类型添加数据的时候源数据会改变
-
深拷贝 不可变数据类型共用,可变数据类型新开辟空间也共用
-
-
pass的作用
-
占位,让代码能继续执行下去
-
-
。。
-
b=[1,2,4,5,['b','c','d'],5]
-
c = [1,2,4,5,['b','c','d']]
-
d = [1,2,4,5,['b','c','d'],5]
-
-
99乘法表
for i in range(10):
for j in range(i):
j = j+1
print(f'{j}x{i}={j*i}',end=' ')
print('')
i = 1
while i<=9:
# 这个位置写代码
j = 1
while j<= i:
# "谁"*"谁"="谁"
print("%d*%d=%2d" % (i,j,i*j),end=" ")
j+=1
# 打印换行
print()
i+=1
-
斐波那契数列
def fib_loop(n):
a, b = 0, 1
for i in range(n + 1):
a, b = b, a + b
return a
for i in range(20):
print(fib_loop(i), end=' ')
# 方法一
lst = [1,1]
for i in range(10):
lst.append(lst[-1] + lst[-2])
print(lst)
# 方法二
a,b = 0,1
for i in range(10):
print(b)
a,b = b,a+b
# 方法三
def fib(n):
if n <= 2:
return 1
# 上一个值 + 上上个值
return fib(n-1) + fib(n-2)
print(fib(6)) -
去除列表中的重复值
a=[1,2,3,3,4,5,5]
a=list(set(a))
print(a) -
读取大文件
def read_line(path):
with open(path, 'r', encoding='utf-8') as f:
line = f.readline()
while line:
line = f.readline()
print(line) -
a = dict(zip(("a","b","c","d","e"),(1,2,3,4,5))) a是什么
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
-
lambda关键字的作用
-
匿名函数,这个函数没有名字,不能在别的地方调用
-
-
*args和**kwargs
-
*args 接收多余的位置参数转化为元祖
-
*kwargs 接收多余的关键字参会素转化为字典
-
-
如何在函数中声明一个全局变量
-
在函数的内部,通过global声明,使在函数内部中设置一个全局变量,这个全局变量可以在任意的函数中进行调用
-
-
filter,map,reduce的作用
-
filter 过滤函数 指定过滤的规则 要过滤的数据
-
map 映射函数 将可迭代对象中每一个元素都执行指定的函数
-
reduce (函数,可迭代对象)累计算
-
-
。。
-
匿名函数也叫一行函数,就是没有名字的函数
-
lambda==def
-
不能在别的地方调用
-
省去定义的过程,代码简洁
-
-
Python中递归的最大层数
-
windows中最大的998
-
-
。。
-
迭代器:具有iter()和next()两个方法
-
迭代对象:只要具有iter()方法
-
-
生成器
-
生成器的本质就是迭代器
-
生成器是程序员自己写的一个迭代器
-
在函数体中出现yield就表明这是一个生成器
-
-
装饰器
-
开放封闭原则
-
在不修改原始代码和调用代码的前提下对待吗进行添加功能和装饰
-
-
反射
-
通过字符串操作对象的属性个方法
-
-
普通装饰器
def warp(func):
def inner(*args,**kwargs):
print('222')
func()
print('333')
return inner
@warp
def foo():
print('11111')
foo() -
有参装饰器
def auth(hh):
def warp(func):
def inner(*args,**kwargs):
if hh:
print('222')
func()
print('333')
else:
print('heihei')
return inner
return warp
@auth(0)
def foo():
print('11111')
foo() -
...
-
[6,6,6,6]
-
-
def func(a,b=[]) 这种写法有什么坑?
-
第一次执行的时候实例化了一个列表,第二次执行的时候用的还是第一次实例的列表,以此类推
-
-
。。
-
v1=[1,3]
-
v2 = [10,20,2]
-
v3 = [1,3]
-
-
..
-
v1=[1]
-
v2 = [10,20,2]
-
v3 = [1,3]
-
-
..
ip = "10.3.9.12"
strvar = ""
for i in ip.split("."):
bin_str = str(bin(int(i)))[2:]
# 总长度是8 原字符串居右
strvar += bin_str.rjust(8,"0")
print(strvar)
# 把二进制字符串转换成十进制,默认转换时,是十进制
print(int(strvar,2))
# 方法二
ip = "10.3.9.12"
strvar = ""
for i in ip.split("."):
# format 将整型转化成二进制,不够8位的拿0补位
strvar += format(int(i) , "08b")
print(int(strvar,2)) -
.
import os
def getallsize(pathvar):
size = 0
lst = os.listdir(pathvar)
print(lst)
for i in lst:
pathvar2 = os.path.join(pathvar,i)
print(pathvar2)
# 判断是否是文件
if os.path.isfile(pathvar2):
size += os.path.getsize(pathvar2)
# 判断是否是文件夹
elif os.path.isdir(pathvar2):
size += getallsize(pathvar2)
print(size)
return size
# "E:\串讲基础\day2\test\1.txt"
pathvar = r"E:\串讲基础\day2\test"
res = getallsize(pathvar) -
5
-
reduce (函数,可迭代对象)累计算
-
-
match 从开头位置查找,找不到就返回none
-
search 任意位置开始查找,找到一个就停止,找不到返回none
-
-
用Python匹配HTML tag的时候,<.>和<.?>有什么区别?
-
<.>会匹配到所有的tag
-
<.?>只会匹配到一个
-
-
如何生成一个随机数?
-
random.random()生成0-1之间的随机数
-
random.randint(a,b)生成a-b之间的随机数
-
random.choice(list) 从参数里面随机抽取一个
-
-
super的作用?
-
调用父类的一个方法
-
-
双下划线和单下划线的区别?
-
__ xxx __双下划线指的是特殊变量可以直接访问
-
_.xxx单下划线表示私有方法或属性
-
-
@staticmethod和@classmethod的区别?
-
都不需要实例化,可以直接调用类里面的方法
-
@staticmethod静态属性,不依赖于对象和类,就是一个普通的函数
-
@classmethod 类方法
-
-
实现一个单例模式(加锁)。
import threading
lock = threading.RLock()
class Singleton:
isinstance = None
def __new__(cls, *args, **kwargs):
if cls.isinstance:
return cls.isinstance
with lock:
if cls.isinstance:
return cls.isinstance
cls.isinstance = object.__new__(cls)
return cls.isinstance
def tack(user):
user = Singleton()
print(user)
for i in range(10):
s=threading.Thread(target=tack,args=(i,))
s.start() -
栈和队列的区别?
-
棧 先进后出
-
队列 先进先出
-
-
以下代码输出是什么? 请给出答案并解释。
class Parent(object):
x = 1
class Child1(Parent):
pass
class Child2(Parent):
pass
print Parent.x, Child1.x, Child2.x
Child1.x = 2
print Parent.x, Child1.x, Child2.x
Parent.x = 3
print Parent.x, Child1.x, Child2.x
1 1 1
1 2 1
3 2 3 -
参考下面代码片段
class Context():
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
# 相当于在最后,执行了文件的关闭操作,fp.close()
print("abc123")
def do_something(self):
print(1111)
with Context() as ctx:
ctx.do_something()
print(ctx)
第二部分 可选题
-
如何获取列表中第二大的值?
-
先pop出最大的,再取最大的
-
排序取最后一个或者倒序取第一个
lst = set([98,1,100,3,-100,50,100,100])
res = sorted(lst)
res_new = res[-2]
print(res_new)
-
-
简述Python内存管理机制。
-
简述Python的垃圾回收机制。
-
请用两个队列来实现一个栈。
from queue import Queue
class Stack():
def __init__(self):
self.master_queue = Queue()
self.minor_queue = Queue()
def push(self,val):
# 入栈
self.master_queue.put(val)
def pop(self):
# 出栈
# 如果队列中没有任何值,直接返回None
if self.master_queue.qsize() == 0 :
return None
while True:
# 当队列总长度为1的时候,循环终止,把最后一个元素拿出来,为了满足栈后进先出的特点
if self.master_queue.qsize() == 1:
value = self.master_queue.get()
break
# 剩下还没有拿出来的元素,暂时放在2号队列中存储
self.minor_queue.put(self.master_queue.get())
"""
minor_queue(1)
master_queue(2 3 4)
minor_queue(2)
master_queue(3 4)
minor_queue(3)
master_queue(4)
"""
# 交换队列,重新循环,继续去最后一个值,如法炮制
self.master_queue,self.minor_queue = self.minor_queue,self.master_queue
return value
obj = Stack()
obj.push("a")
obj.push("b")
obj.push("c")
print(obj.pop()) # c
print(obj.pop()) # b
print(obj.pop()) # a
print(obj.pop()) # a -
请用Python实现一个链表。
class Node():
def __init__(self, value, next):
self.value = value
self.next = next
head = Node("头", None)
last = head
for i in range(5): # v0 v1 v2 v3 v4
node = Node("v%s" % i, None)
last.next = node
last = node
# 查看链表的关系
print(head.value)
print(head.next.value)
print(head.next.next.value)
print(head.next.next.next.value)
print(head.next.next.next.next.value)
print(head.next.next.next.next.next.value)
-
请用Python实现链表的逆转。
def reverse_link_list(head):
# 要是空的,或者None,直接返回head
if not head or not head.next:
return head
# 获取上一个节点对象
prev_node = None
# 获取下一个节点对象
next_node = head.next
# 获取当前节点对象
current_node = head
while True:
# 修改next,所指向的对象
current_node.next = prev_node
# 如果下一个阶段对象是None
if not next_node: # not None
break
# 重新获取上一个对象,即把当前丢向单独存一份,以准备第二次循环时插进next属性中
prev_node = current_node
# 重新获取当前对象 , 即把下一个对象单独存储起来(下个)
current_node = next_node
# 重新获取下一个对象,即把下一个对象单独存储起来,所指向的下个新对象赋值给next_node(下下个)
next_node = current_node.next
return current_node
head = reverse_link_list(head)
print(head.value)
print(head.next.value)
print(head.next.next.value)
print(head.next.next.next.value)
print(head.next.next.next.next.value)
print(head.next.next.next.next.next.value)
-