关于Python程序的运行性能方面的问题,以及面试的一些笔试题

1.现有一列表alist, 请写出两种去除 alist 中重复元素的方法,其中:

  • 要求保持原有列表中元素的排列顺序。

# 第一种
alist = ['a','b','a','v','c','b']
alist1 = list() #初始化静态列表
for var in alist: #遍历列表元素
    if var not in alist1: #判断遍历元素是否在空列表中, 不在就进行添加
        alist1.append(var)
    else:
        pass
print(alist1)

# 第二种
alist = ['a','b','a','v','c','b']
alist1 = list(set(alist)) #队列表去重
alist1.sort(key = alist.index) #对去重后的列表进行排序
print(alist1)

# 第三种
alist = ['a','b','a','v','c','b']
alist.sort() #先对列表进行排序
del_lst = [] #初始化静态列表
for i in range(len(alist) - 1): #循环构建下标
    if alist[i] == alist[i + 1]: #相邻两位置的元素相等,将相同的后一位元素添加到 空列表
        del_lst.append(alist[i + 1])
for j in del_lst: #遍历del_lst元素列表 对alist进行remove删除元素
    alist.remove(j)
print(alist)

# 第四种
# fromkeys 是把所有的键都赋同样的值(如果不指定内容则默认赋值为None)
alist = ['a','b','a','v','c','b']
alist1 = []
dct = dict.fromkeys(alist) 
for n in dct: #遍历读出key值添加到空列表中
    alist1.append(n)
print( alist1)

  • 无需考虑原有列表中元素的排列顺序。
alist = [1,2,3,4,5,5,6]
print(list(set(alist))
  1. 请描述Unicode,utf-8,gbk等编码之间的区别?
    简单来说unicode,gbk和大五码就是编码的值,而utf-8,uft-16之类就是这个值的表现形式
十进制Unicode编码UTF-8字节流
0-127位0x0000000x00007F0xxxxxxx(7位)
128-2047位0x000080-0x0007FF110xxxxx 10xxxxxx(11位)
2048-65535位0x0008xx-0x00FFFF1110xxxx 10xxxxxx 10xxxxxx(16位)
65536-1114111位0x010000-0x10FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(21位)
  1. 关于Python程序的运行性能方面,有什么手段能提升性能?

1. 使用局部变量
尽可能使用局部变量替代全局变量,可以是程序易于维护并且有助于提高性能节约成本。

2. 减少函数调用的数量
当需要确定对象类型时,使用isinstance()方法最好,id()次之,type()最差。

#确定变量num是否是整数
#三种方式
type(num) == type(0) # ==判断
type(num) is type(0) # is 身份比较
isinstance(num,(int)) # #调用这个函数比较

为了避免重复计算,不要把重复操作作为参数放入循环中。

# 直接
while i < len(a):
    pass
# 间接
m = len(a)
while i < m:
    pass

3. 使用映射来替换条件搜索
映射(例如dict,等等)的搜索速度比条件语句(例如if,等等)快很多。在Python中没有select-case语句。

#  if reach
if a == 1:
    b = 10
elif a == 2:
    b = 20
...

# dict reach , better performance
d = {1:10,2:20,...}
b =d[a]

4. 直接迭代序列元素

alist = [1,2,3]

# Iterate elements/迭代元素
for item in alist:
    print(item)
    
# Iterate indexes/迭代索引
for i in range(len(a)):
    print(a[i)

5. 用生成器表达式替换列表解析

列表解析生成整个列表,会对大量数据的迭代产生负面作用。而生成器表达式不会。生成器表达式不会创建一个列表,相反返回一个生成器,在需要的时候生成具体值(延迟的),这种方式对内存友好。

# List analysis/列表推导式
l = sum([len(word) for line in f for word in line.split()])

# generator expression/生成器表达式
l = sum(len(word) for line in f for word in line.split())

6. 先编译后调用
当使用函数eval()和exec()来执行代码时,最好调用代码对象(通过compile()函数预先编译成字节码)而不是直接调用str,这样可以避免重复编译过程多次和提高程序的性能。 正则表达式模式匹配是类似的。 在执行比较和匹配之前,最好将正则表达式模式编译为正则表达式对象(通过re.complie()函数)。

7. 模块编程的习惯
模块中最高级别的Python语句(无缩进代码)将在导入模块时执行(是否真的需要执行)。 因此,您应该尝试将模块的所有功能代码放入函数中(与主程序相关的功能代码也可以放入main()函数,主程序本身调用main()函数)。 测试代码可以写在模块的main()函数中。 将在主程序中检测__name__的值。 如果是"main"(表示模块是直接执行的),则调用main()函数进行测试; 如果它是模块的名称(表示模块被调用),则不会执行测试。

7.1 : 什么是模块化编程?

**1:模块定义**
     **模块**:用来从逻辑上组织Python代码(变量,函数、类,逻辑:实现一个功能),本质就是.py结尾的Python文件(文件名:test.py,对应的模块名,test)。

     **包**:本质就是一个文件夹或者是目录(必须带有一个_init_.py文件),包是用来从逻辑上组织模块的。

**2.导入方法:**
        1):import module_test, module_test1 (调用方法的时候,需要module_test.2):form moudule_test import ** 表示所有的方法)(不建议使用,这个就相当于导入了程序。)  容易造成覆盖,出现问题。

        3):form module_test import module_ajun  as module_ajun_test(作为一个别名来使用)
**3:import本质 (路径 搜索和搜索路径)**
        1)      import module_test  
		        相当于把module_test 的所有代码解释一遍,全部传递给module_test.
		         调用module_test的变量和方法。

        2)      form moudule_test import name 
        		相当于值调用了name变量,在当前模块,就不需要加前缀了。

总结:导入模块的本质就是把Python文件解释一遍。(import test test=’test.py all code’)

导入包的本质就是执行包下面的_init_.py文件

Import module_name–》mudule_name.py–》module_name.py的路径–》sys.path

os模块主要方法

需要注意的是,Windows系统与Linux系统不同,所有有些方法无法在Windows系统上进行调试

os.sep:取代操作系统特定的路径分隔符
os.name:指示你正在使用的工作平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'。
os.getcwd:得到当前工作目录,即当前python脚本工作的目录路径。
os.getenv()和os.putenv:分别用来读取和设置环境变量
os.listdir():返回指定目录下的所有文件和目录名
os.remove(file):删除一个文件
os.stat(file:获得文件属性
os.chmod(file):修改文件权限和时间戳
os.mkdir(name):创建目录
os.rmdir(name):删除目录
os.removedirs(r“c:\python”):删除多个目录
os.system():运行shell命令
os.exit():终止当前进程
os.linesep:给出当前平台的行终止符。例如,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'
os.path.split():返回一个路径的目录名和文件名
os.path.isfile()和os.path.isdir()分别检验给出的路径是一个目录还是文件
os.path.existe():检验给出的路径是否真的存在
os.listdir(dirname):列出dirname下的目录和文件
os.getcwd():获得当前工作目录
os.curdir:返回当前目录('.')
os.chdir(dirname):改变工作目录到dirname
os.path.isdir(name):判断name是不是目录,不是目录就返回false
os.path.isfile(name):判断name这个文件是否存在,不存在返回false
os.path.exists(name):判断是否存在文件或目录name
os.path.getsize(name):或得文件大小,如果name是目录返回0L
os.path.abspath(name):获得绝对路径
os.path.isabs():判断是否为绝对路径
os.path.normpath(path):规范path字符串形式
os.path.split(name):分割文件名与目录(事实上,如果你完全使用目录,它也会将最后一个目录作为文件名而分离,同时它不会判断文件或目录是否存在)
os.path.splitext():分离文件名和扩展名
os.path.join(path,name):连接目录与文件名或目录
os.path.basename(path):返回文件名
os.path.dirname(path):返回文件路径

form .(点表示当前目录,就是_init_的目录) import 包名

4.导入优化
import module_test

def logger():
    module_test.test()
    print('通过modile_test找test()')
# 怎么优化?每次都去找,很浪费时间?

# 使用from module_test  import test 这个方法,节约时间。
from module_test  import test

def search():
    test()
    print('.....')
    
5.模块的分类
    A:标准库

    B:开源模块
    
    C:自定义模块
  • 总结了一些小的技巧:

    1. 大数据求和 使用sum /小数据求和时 直接加会更快
    2. 合理使用copy和deepcopy
import copy
import time
a =[]
# 百万数据的测试
for i in range(1000000):
    a.append(i)
# 浅拷贝
start = time.time()
copy.copy(a)
end = time.time()
running_time = end-start
print('time cost : %.5f sec' %running_time)
# 输出结果:
time cost : 0.01496 sec


# 深拷贝
start1 = time.time()
copy.deepcopy(a)
end1 = time.time()
running_time1 = end1-start1
print('time cost : %.5f sec' %running_time1)
# 输出结果:
time cost : 0.69713 sec
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lonelypatients°

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值