Python零基础速成班-第8讲-Python文件操作File I&O、高级文件处理模块shutil、CSV、JSON、多线程基础

Python零基础速成班-第8讲-Python文件操作File I&O、高级文件处理模块shutil、CSV、JSON、多线程基础

学习目标

  1. 文件操作File I/O
  2. 高级文件处理模块shutil
  3. CSV、JSON、多线程基础
  4. Python块(Modules)和包(Packages)介绍
  5. 课后作业(4必做1扩展)

友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连续执行。

1、文件操作File I/O

Python中对文件的操作通常按照以下三个步骤进行:

  1. 使用open()函数打开(或建立)文件,返回一个file对象。
  2. 使用file对象的读/写方法对文件进行读/写的操作,read()方法读取文件,write()方法写入文件。
  3. 使用file对象的close()方法关闭文件。
我们常用:打开冰箱门,把大象装进冰箱,关上冰箱门来形容,加深记忆。

进阶提示:

①如果忘记关闭文件,会造成系统资源消耗,而且会影响到后续对文件的访问。
②文件操作方法执行后,会把文件指针移动到文件的末尾。

1.1 打开文件Open a file

打开模式的第一个字母表示:
第一个字母代表的意思
r:以只读形式打开文件(默认,可以省略),文件不存在时报错
w:以只写形式打开文件,文件不存在时,则创建文件,文件存在时会清除并覆盖原有内容
x:文件不存在时新建文件并写入,文件存在则报错
a:如果文件存在,在文件末尾追加写入内容
打开模式的第二个字母表示:
第二个字母代表的意思
t:以文本text或者超文本html-HyperText协议打开(默认,可以省略)
b:以二进制binary模式打开

下例中,我们将当前时间写入D盘根目录下test1.txt文件中,打开文件,有today is 2022-05-09 11:42:19的内容。

import time
file0 = open('D://test1.txt','wt')
ret = file0.write("today is {}".format(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())))##return len of write
print("return value of write()=",ret)
file0.close()
return value of write()= 28

我们将"Python之禅"写入D盘根目录下test2.txt文件中。

pythonthis = """优美胜于丑陋
明了胜于晦涩
简洁胜于复杂
复杂胜于凌乱
扁平胜于嵌套
可读性很重要
"""
file1 = open("D://test2.txt","wt")
ret1 = file1.write(pythonthis)
print("已写入{}个字符".format(ret1))
file1.close()
已写入42个字符

读取test2文件内容并输出。

file2 = open("D://test2.txt","r")
print(file2.read())
file2.close()
优美胜于丑陋
明了胜于晦涩
简洁胜于复杂
复杂胜于凌乱
扁平胜于嵌套
可读性很重要

1.2 大文件的读取

read()方法默认会把文件的所有内容一次性读到内存,如果文件太大,对内存的占用会非常严重,这时我们就需要使用如下两种方法:

①read(chunk),chunk代表一次读取字符的长度,即分多次读取,直到文件被读取完毕。
②readline()方法,可以一次读取一行内容,方法执行后,会把指针移动到下一行,准备再次读取,直至文件被读取完毕。

每次读取100个字符,内容写入output字符串并不断拼接,最后文件被读取完毕后输出。

bigfile1=open('D://test2.txt','r')
chunk=100
output =''
while True:
    fragment= bigfile1.read(chunk)
    if not fragment:
        break
    output+=fragment
bigfile1.close()
print(output)
优美胜于丑陋
明了胜于晦涩
简洁胜于复杂
复杂胜于凌乱
扁平胜于嵌套
可读性很重要

readline()逐行读取,注意:每读取到末尾都会有一个 \n,使用print输出的时候不会显示 \n换行符。

bigfile2=open('D://test2.txt','r')
output=""
while True:
    fragment= bigfile2.readline()
    if not fragment:
        break
    output+=fragment
bigfile2.close()
output
'优美胜于丑陋\n明了胜于晦涩\n简洁胜于复杂\n复杂胜于凌乱\n扁平胜于嵌套\n可读性很重要\n'

也可以使用readlines()将所有行内容读取到数组list中,可分别调用具体哪一行的内容。

bigfile3=open('D://test2.txt','r')
listlines =bigfile3.readlines()
bigfile3.close()
print("%s\n%s\n%s"%(type(listlines),listlines,listlines[0]))
<class 'list'>
['优美胜于丑陋\n', '明了胜于晦涩\n', '简洁胜于复杂\n', '复杂胜于凌乱\n', '扁平胜于嵌套\n', '可读性很重要\n']
优美胜于丑陋

1.3 大文件的写入

大文件的写入我们可以使用write(text[offset:chunk])的方式,每次写入固定的字符,减少对内存的占用。
text[offset:chunk]中offset为字符指针,chunk为偏移量,下例中偏移量为200,即每次写入200个字符,直至全部写入。

text="""The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
"""
bigfile3 =open('D://test3.txt','wt')
size = len(text)
offset = 0
chunk =200
while offset < size:
    bigfile3.write(text[offset:offset+chunk])
    offset+=chunk
bigfile3.close()

1.4 使用with open()语法,实现文件打开关闭自动化,简化文件操作

它会在使用完毕后,自动关闭文件,无需手动书写close(),推荐大家使用该语法。

with open('D://test3.txt','rt') as file3:# no need close()
    without=file3.read()
print(without)
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

1.5 文件指针位置Position

①tell() 函数用于判断文件指针当前所处的位置,而 seek() 函数用于移动文件指针到文件的指定位置。
②file.seek(offset[, whence])
whence:作为可选参数,用于指定文件指针要放置的位置,该参数的参数值有 3 个选择:0 代表文件头(默认值)、1 代表当前位置、2 代表文件尾。
offset:表示相对于 whence 位置文件指针的偏移量,正数表示向后偏移,负数表示向前偏移。

下例中,指针位于开头0位置,当读取17个字符后,指针位于34位置,因为文件操作方法执行后,会把文件指针移动到文件的末尾,一个中文占用2个位置。

with open('D://test2.txt','rt') as file4:
    print(file4.tell())
    print(file4.read(17))
    print(file4.tell())
0
优美胜于丑陋
明了胜于晦涩
简洁胜
34

下例中,指针放置于文件头向后偏移12的位置,顺势读取10个字符,其中包含换行符\n,两个字符。

with open('D://test2.txt','rt') as file5:
    print(file5.seek(12,0))
    print(file5.read(10))
12

明了胜于晦涩
简洁

2、高级文件处理模块shutil

2.1 OS模块

Python通过os的模块提供了许多系统功能,比如路径、文件、目录等。

文件操作
  1. os.path.abspath() 当前绝对路径
  2. os.path.exists() 文件是否存在
  3. os.path.isfile() 是否是文件
  4. os.path.isdir() 是否是目录
  5. os.listdir() 目录列表
  6. os.rename() 修改文件名
  7. os.remove() 删除文件
import os
print(os.path.abspath('.'))
print(os.path.exists('D://test1.txt'))
print(os.path.isfile('D://test1.txt'))
print(os.path.isdir('D://Program Files (x86)'))
print(os.listdir('D://'))
print(os.rename('D://temp/log/','D://temp/log1/'))
#print(os.remove('D://temp/log1'))
E:\lululearn\Python\PythonCSDN
True
True
True
['$RECYCLE.BIN', 'MSOCache', 'Program Files', 'Program Files (x86)', 'ProgramData', 'System Volume Information', 'temp', 'test1.txt', 'test2.txt', 'test3.txt']
None
目录操作
  1. os.mkdir() 创建目录
  2. os.rmdir() 删除目录
  3. os.chdir() 切换当前目录
import os
os.mkdir('D://mydir')
#os.rmdir('D://mydir')
os.chdir('D://mydir')
print(os.listdir('D://'))
['$RECYCLE.BIN', 'MSOCache', 'mydir', 'Program Files', 'Program Files (x86)', 'ProgramData', 'System Volume Information', 'temp', 'test1.txt', 'test2.txt', 'test3.txt']

2.2 shutil模块

shutil 拷贝文件

import shutil
import os
shutil.copy('D://test1.txt','D://mydir/test1.txt')
os.listdir('D://mydir')
['test1.txt']

shutil 拷贝目录

拷贝包括所有文件和子文件夹,一起拷贝到路径目标处的文件夹,并返回被复制的文件夹的路径。

import shutil
shutil.copytree('D://mydir','D://mydir1')
'D://mydir1'

shutil 移动文件

将在路径源处移动文件或文件夹,并将返回新位置的绝对路径。

import shutil
shutil.move('D://test2.txt','D://mydir/test2.txt')
'D://mydir/test2.txt'

还可以变更为新的文件名称

import shutil#new name
shutil.move('D://test3.txt','D://mydir/test3new.txt')
'D://mydir/test3new.txt'

shutil 删除文件

删除路径文件夹,该路径下所有文件和文件夹也将被删除。

import shutil
shutil.rmtree('D://mydir')

3、CSV、JSON、多线程基础

3.1 CSV文件处理

CSV是以逗号为分隔符的数据文件
创建一个CSV文件,并保存到D盘根目录

import csv
csvlist =[
    ["marry","kate"],
    ["jim","poly","lucy"],
    ["李雷","韩梅梅"],
    "张老师"
]
with open('D://english.csv','w') as csvfile:
    csvout= csv.writer(csvfile)
    csvout.writerows(csvlist)

打开CSV文件循环输出内容

with open('D://english.csv','r') as csvfile1:
    csvin =csv.reader(csvfile1)
    print([row for row in csvin])
[['marry', 'kate'], [], ['jim', 'poly', 'lucy'], [], ['李雷', '韩梅梅'], [], ['张', '老', '师'], []]

3.2 JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写。
使用 JSON 函数需要导入 json 库:import json。

Python常用JSON函数

①json.dumps 将 Python 对象编码成 JSON 字符串
②json.loads 将已编码的 JSON 字符串解码为 Python 对象
③我们常用pprint格式化打印JSON字符串

进阶提示:
json.dumps()将 Python 对象编码成 JSON 字符串时,会将中文转换成 Unicode 编码。我们需要在 dumps 设置参数 ensure_ascii=False

import json
import pprint
from pprint import pprint
hrm={
        "lastname": "赵刚",
        "orgname": "综合管理室",
        "gender": "男",
        "nationality": "汉族",
        "positionname": "能源管理",
        "politic": "中国共产党党员",
        "education": [{"全日制":"大专"},{"继续教育":"自考本科"}],
        "professtion": "助理工程师"
      }
jsonstr = json.dumps(hrm,ensure_ascii=False)#JSON TO STR

print(jsonstr,'\n')

hrmjson = json.loads(jsonstr)#STR TO JSON
print(hrmjson,'\n')

pprint(hrmjson)#格式化打印
{"lastname": "赵刚", "orgname": "综合管理室", "gender": "男", "nationality": "汉族", "positionname": "能源管理", "politic": "中国共产党党员", "education": [{"全日制": "大专"}, {"继续教育": "自考本科"}], "professtion": "助理工程师"} 

{'lastname': '赵刚', 'orgname': '综合管理室', 'gender': '男', 'nationality': '汉族', 'positionname': '能源管理', 'politic': '中国共产党党员', 'education': [{'全日制': '大专'}, {'继续教育': '自考本科'}], 'professtion': '助理工程师'} 

{'education': [{'全日制': '大专'}, {'继续教育': '自考本科'}],
 'gender': '男',
 'lastname': '赵刚',
 'nationality': '汉族',
 'orgname': '综合管理室',
 'politic': '中国共产党党员',
 'positionname': '能源管理',
 'professtion': '助理工程师'}

3.3 多线程基础Concurrency

线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。

多线程使用说明:

①使用了多线程并发的操作,可以明显降低程序消耗的时间。
②当调用start()时,才会真正的创建线程,并且开始执行。
③每个线程都有一个唯一标示符,来区分线程中的主次关系,主线程:mainThread,Main函数或者程序主入口,都可以称为主线程。
④子线程:Thread-x 使用 threading.Thread() 创建出来的都是子线程。
⑤语法:threading.Thread(target=需要调用的函数,args或者kwargs可向函数传递参数),如threading.Thread(target=do_this, args=(10,20), kwargs={“b”:100,“c”:200})。
⑥多线程程序的执行顺序是不确定的,可以通过time.sleep()让线程进入固定时间休眠状态,到sleep结束后,线程进入就绪(Runnable)状态,等待调度。

python的多线程模块threading极大的简化了线程操作,可以更加方便的被使用。下例中,do_this函数为主程序,通过threading.Thread构建多线程并调用。案例中为主线程调用,不涉及子线程。

import threading
    
def do_this(what):
    print("当前线程ID是: %s   主程序来自: %s"%(threading.current_thread(),what))
    
if __name__ == '__main__':
    for i in range(5):
        p = threading.Thread(target=do_this,args=("第 %s 线程的调用"%i,))
        p.start()
当前线程ID是: <Thread(Thread-91, started 9060)>   主程序来自: 第 0 线程的调用
当前线程ID是: <Thread(Thread-92, started 2996)>   主程序来自: 第 1 线程的调用
当前线程ID是: <Thread(Thread-93, started 9756)>   主程序来自: 第 2 线程的调用
当前线程ID是: <Thread(Thread-94, started 1216)>   主程序来自: 第 3 线程的调用
当前线程ID是: <Thread(Thread-95, started 8648)>   主程序来自: 第 4 线程的调用

加入子线程(即在主程序中执行的多次作业),如下代码,主线程已经结束(其实并没有真正结束),子线程还在继续执行。

import threading
from time import sleep,ctime
 
def sing():
    for i in range(4):
        print("正在唱歌...%d\n"%i)
        sleep(1)

def dance():
    for i in range(4):
        print("正在跳舞...%d\n"%i)
        sleep(1)
    
if __name__ == '__main__':
    print('---开始---:%s'%ctime())
 
    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)
 
    t1.start()
    t2.start()
    
    print('---结束---:%s'%ctime())
---开始---:Tue May 10 11:32:45 2022
正在唱歌...0

正在跳舞...0

---结束---:Tue May 10 11:32:45 2022
正在跳舞...1
正在唱歌...1


正在跳舞...2
正在唱歌...2


正在跳舞...3
正在唱歌...3

守护线程:如果在程序中将子线程设置为守护线程,则该子线程会在主线程结束时自动退出,设置方式为thread.setDaemon(True),主线程加入exit(),在thread.start()之前设置。

import threading
from time import sleep,ctime
 
def sing():
    for i in range(4):
        print("正在唱歌...%d\n"%i)
        sleep(1)

def dance():
    for i in range(4):
        print("正在跳舞...%d\n"%i)
        sleep(1)
    
if __name__ == '__main__':
    print('---开始---:%s'%ctime())
 
    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)
    t1.setDaemon(True)#线程守护
    t2.setDaemon(True)
 
    t1.start()
    t2.start()
    
    print('---结束---:%s'%ctime())
    exit()
---开始---:Tue May 10 11:40:10 2022
正在唱歌...0

正在跳舞...0

---结束---:Tue May 10 11:40:10 2022

4、Python块(Modules)和包(Packages)介绍

在刚入门python时,模块化编程、模块、类库等术语常常并不容易理清。尤其是Modules(模块)和Packages(包),在import引用时很容易混淆出错。
实际上,Python中的函数(Function)、类(Class)、模块(Module)、包库(Package),都是为了实现模块化引用,让程序的组织更清晰有条理。

  • 通常,函数、变量、类存储在被称为模块(Module)的.py文件中,一组模块文件又组成了包(Package)。
  • 将函数、变量、类存储在存储在独立的.py文件中,可隐藏代码实现的细节,将不同代码块重新组织,与主程序分离,简化主程序的逻辑,提高主程序的可读性。
  • 有了包和模块文件,可以在其他不同程序中进行复用,还可以使用其他人开发的第三方依赖库。

引入数学包,这里的math就是一个Packages。

import math
math.pow(2,4)
16.0

引入模块,这里choice就是random下面的模块。

from random import choice
possibilites =['dog','cat','bird','fish','tiger']
choice(possibilites)
'tiger'

也可以引入Packages,在程序中使用modules.func实现调用。

import random
possibilites =['dog','cat','bird','fish','tiger']
random.choice(possibilites)
'tiger'

5、课后作业,答案在下一讲

1、生成多个邮件内容的数据字典并打印。

邮件姓名name列表存于D盘根目录下name.txt,内容为
"""张三
李四
王五
"""
邮件主题subject为"I Love Python",内容存放于D盘根目录下body.txt,内容为
"""Beautiful is better than ugly.
Explicit is better than implicit.
"""
通过程序为每个人生成一个邮件内容的数据字典 格式为{“name”:{“subject”:" “,“content”:” "}},使用pprint打印出来
您的代码:

2、通过代码提取.jpg图片文件的长、高信息,不使用任何现成的库文件。图片的网络位置是"https://pica.zhimg.com/v2-6c272f6470a98eca718c2fd550bbd804_1440w.jpg?source=172ae18b" ,请下载后保存到D盘根目录,命名为Python.jpg。

提示:
1.高的信息在jpg byte文件的第164位,2字节,宽信息是之后的2字节
2.通过file.seek()语法将指针放置于163位,取2个字节位高,再取两个字节为宽
3.byte使用偏移算法转化为数字:byte[0]<<8+byte[1]

您的代码:

3、创建一个《Python之禅.txt》的文件,将下列内容写入文件中,并保存在D盘根目录下。

优美胜于丑陋
明了胜于晦涩
简洁胜于复杂
复杂胜于凌乱
扁平胜于嵌套
可读性很重要

tips:可以使用 open write close三步走,或者使用with open语法

您的代码:

4、使用递归计算,有一堆8两重的苹果,你要切成重量相等的若干份,每一份重量不大于1两,你会怎么切?

先切两份,A1,A2

再把A1细分,A11,A12,再把A2细分,A21,A22

再把A11细分两份,直到都小于1两

您的代码:

*(扩展)5、The Digit’s Image Data 数字图像学习。

数字图像数据是一个3D列表。本案例围绕它构建。运行下面的代码检索100个示例数据。取第一组数据。
扩展:(sklearn)是机器学习中常用的第三方模块,对常用的机器学习方法进行了封装,包括回归(Regression)、降维(Dimensionality Reduction)、分类(Classfication)、聚类(Clustering)等方法。
from sklearn import datasets
import random
random.seed(2016)#随机数种子,当使用random.seed(x)设定好种子之后,其中x可以是任意数字,比如10,那么每次调用生成的随机数将会是同一个。
digit_data = dict(datasets.load_digits())#读取数字图像学习库
sample_index =random.sample(range(len(digit_data['images'])),100)#取100个sample
digit_image =[digit_data['images'][i] for i in sample_index]#数字图像
digit_true_label=[digit_data['target'][i] for i in sample_index]
print(digit_image[0])
[[ 0.  0.  3. 12. 16.  9.  0.  0.]
 [ 0.  0. 12.  9. 13. 16.  9.  0.]
 [ 0.  3. 16.  5.  0.  8. 12.  0.]
 [ 0.  0.  9. 16. 10. 13.  2.  0.]
 [ 0.  0.  0.  4. 16. 12.  0.  0.]
 [ 0.  0.  0. 11.  9. 16.  0.  0.]
 [ 0.  0.  1. 15.  2. 12.  0.  0.]
 [ 0.  0.  2. 16. 16.  6.  0.  0.]]

Question1: show the image by using the following code 输出数字图像。

import matplotlib.pyplot as plt
%matplotlib inline
sample_2d_array =digit_image[22]
plt.imshow(sample_2d_array,plt.cm.gray_r)
plt.show()

在这里插入图片描述

Question2: show thematrix by using the following code 输出数字矩阵。

import copy
new_image = copy.copy(digit_image[digit_true_label.index(0)])
print(new_image)#原始图像
for row in range(len(new_image)):
    for col in range(len(new_image[row])):
        if new_image[row][col] >10:#图像越深数值越大,我们这里取大于10,则取1
            new_image[row][col] =1
            
        else:
            new_image[row][col] =0
print(new_image)#编辑后的图像
#图像处理
import matplotlib.pyplot as plt
plt.imshow(new_image,plt.cm.gray_r)

import numpy as np
for(i,j),value in np.ndenumerate(new_image):
    if value<1:
        plt.text(j,i,int(value),ha='center',va='center',color="#000000")
    else:
        plt.text(j,i,int(value),ha='center',va='center',color="#FFFFFF")

[[ 0.  0.  0.  9. 13.  3.  0.  0.]
 [ 0.  0.  8. 15. 12. 15.  2.  0.]
 [ 0.  0. 12.  8.  0. 15.  4.  0.]
 [ 0.  3. 13.  0.  0. 10.  7.  0.]
 [ 0.  8.  9.  0.  0. 13.  7.  0.]
 [ 0.  2. 16.  4.  7. 16.  5.  0.]
 [ 0.  0. 14. 14. 16. 15.  1.  0.]
 [ 0.  0.  1. 12. 14.  4.  0.  0.]]
[[0. 0. 0. 0. 1. 0. 0. 0.]
 [0. 0. 0. 1. 1. 1. 0. 0.]
 [0. 0. 1. 0. 0. 1. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 1. 0. 0. 1. 0. 0.]
 [0. 0. 1. 1. 1. 1. 0. 0.]
 [0. 0. 0. 1. 1. 0. 0. 0.]]

在这里插入图片描述

6、上一讲Python零基础速成班-第7讲-Python注释、算法基础、排序、查找、时间复杂度 课后作业及答案

1、完成一个包含文档注释的函数(函数功能为两个数相除),注释风格为主流reST Style,包含param,return,raise,design by,createdate等关键字。

def divfunc(num1,num2):
    '''两个数相除的函数
    :param num1:被除数
    :param num2:除数
    :return:num1除num2后的值
    :raise:异常除数不能为0
    :design by:LuLu with Jupyter notebook
    :createdate:2022-12-20
    '''
    if num2 ==0:
        raise Exception("Divisor cannot be 0")
    return num1/num2
print(divfunc.__doc__)
两个数相除的函数
    :param num1:被除数
    :param num2:除数
    :return:num1除num2后的值
    :raise:异常除数不能为0
    :design by:LuLu with Jupyter notebook
    :createdate:2022-12-20

2、请统计"Hello, have you tried our turorial section yet?" 中每个元音字母各出现了多少次?

vowels ="aeiou"
mystr = "Hello, have you tried our turorial section yet?" 
counter = {c:mystr.count(c) for c in vowels}
print(counter)
{'a': 2, 'e': 5, 'i': 3, 'o': 5, 'u': 3}

3、根据公式 n ∗ ( n − 1 ) n * (n-1) n(n1),生成一个100个数组的列表,例如:

[0,2,6,12,20,30,42…]

print(list(map(lambda n:n*(n-1),[i for i in range(1,101)])))
[0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306, 342, 380, 420, 462, 506, 552, 600, 650, 702, 756, 812, 870, 930, 992, 1056, 1122, 1190, 1260, 1332, 1406, 1482, 1560, 1640, 1722, 1806, 1892, 1980, 2070, 2162, 2256, 2352, 2450, 2550, 2652, 2756, 2862, 2970, 3080, 3192, 3306, 3422, 3540, 3660, 3782, 3906, 4032, 4160, 4290, 4422, 4556, 4692, 4830, 4970, 5112, 5256, 5402, 5550, 5700, 5852, 6006, 6162, 6320, 6480, 6642, 6806, 6972, 7140, 7310, 7482, 7656, 7832, 8010, 8190, 8372, 8556, 8742, 8930, 9120, 9312, 9506, 9702, 9900]

4、制作一个Length Uint Converter,通过dict快速实现①选择转换类型②参数输入③结果输出

1英寸inch=25.4毫米
1英尺feet=30.5厘米
1英里mile=1.61公里
1码yard=0.914米
1浪wave=204米
length={
    "in":lambda x:print(f'{x*25.4}毫米'),
    "ft":lambda x:print(f'{x*30.5}厘米'),
    "mi":lambda x:print(f'{x*1.61}公里'),
    "yr":lambda x:print(f'{x*0.914}米'),
    "wv":lambda x:print(f'{x*204}米')
}
for k in length.keys():
    length[k](1)
25.4毫米
30.5厘米
1.61公里
0.914米
204米

*(挑战) 5、编程实践项目

大数据下:比较两种排序的效率情况

随机从0~100000中,取1000个整数,填入数组,分别进行冒泡排序和归并排序(两种方法可参考上文书写),比较它们的效率(执行耗时)。再取10000个整数,再试试执行效率。将程序写进class,分别通过class+函数名调用方法。

tips:函数运行时间可以使用下列函数

def timer(f):
    def _f(*args):
        t0=time.time()
        f(*args)
        return time.time()-t0
    return _f
import random
import time
class efficiency:
    
    def timer(f):#运行时间函数
        def _f(*args):
            t0=time.time()
            f(*args)
            return time.time()-t0
        return _f

    def bubble_Sort(list):#冒泡排序方法
        for i in range(1,len(list)):
            for j in range(0,len(list)-i):
                if list[j] > list[j+1]:
                    list[j],list[j+1]=list[j+1],list[j]
        return list

    def merge_Sort(list):#归并排序方法
        n = len(list)#获取长度
        if n <=1:#如果列表长度1,直接返回
            return list
        mid = n//2 #取中间值,把数组拆分
        left = efficiency.merge_Sort(list[:mid])#取左半部分
        right = efficiency.merge_Sort(list[mid:])#取右半部分
        leftp = 0 #左半指针从0开始
        rightp = 0 #右半指针从0开始
        result =[]#定义空数组存储每次归并好的列表
        while leftp < len(left) and rightp < len(right):#当左右指针分别小于长度时
            if left[leftp] <= right[rightp]:
                result.append(left[leftp])
                leftp +=1
            else:
                result.append(right[rightp])
                rightp +=1
        result += left[leftp:]#考虑数组为奇数,把最后元素添加进来
        result += right[rightp:]
        return result
    
btime1000=efficiency.timer(efficiency.bubble_Sort)(random.sample(range(0,100000),1000))
mtime1000=efficiency.timer(efficiency.merge_Sort)(random.sample(range(0,100000),1000))
btime10000=efficiency.timer(efficiency.bubble_Sort)(random.sample(range(0,100000),10000))
mtime10000=efficiency.timer(efficiency.merge_Sort)(random.sample(range(0,100000),10000))
print(f"1000个整数排序bubble是merge的{btime1000/mtime1000}倍")
print(f"10000个整数排序bubble是merge的{btime10000/mtime10000}倍")
1000个整数排序bubble是merge的21.74628025097102倍
10000个整数排序bubble是merge的232.91922496225465倍
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值