周末班——day3


閱讀目錄

拾遺

集合

https://www.cnblogs.com/Eva-J/articles/6993515.html

在for循環中修改被循環的對象

 

 

文件處理

初窺文件操作基本流程

計算機系統分為:計算機硬件,操作系統,應用程序三部分。

我們用python或其他語言編寫的應用程序若想要把數據永久保存下來,必須要保存於硬盤中,這就涉及到應用程序要操作硬件,眾所周知,應用程序是無法直接操作硬件的,這就用到了操作系統。操作系統把復雜的硬件操作封裝成簡單的接口給用戶/應用程序使用,其中文件就是操作系統提供給應用程序來操作硬盤虛擬概念,用戶或應用程序通過操作文件,可以將自己的數據永久保存下來。

有了文件的概念,我們無需再去考慮操作硬盤的細節,只需要關注操作文件的流程:

#1. 打開文件,得到文件句柄並賦值給一個變量
#2. 通過句柄對文件進行操作
#3. 關閉文件
#1. 打開文件,得到文件句柄並賦值給一個變量
f=open('a.txt','r',encoding='utf-8') #默認打開模式就為r

#2. 通過句柄對文件進行操作
data=f.read()

#3. 關閉文件
f.close()
coding:文件操作
#1、由應用程序向操作系統發起系統調用open(...)
#2、操作系統打開該文件,並返回一個文件句柄給應用程序
#3、應用程序將文件句柄賦值給變量f
f=open('a.txt','r')分析

關閉文件的注意事項

打開一個文件包含兩部分資源:操作系統級打開的文件+應用程序的變量。在操作完畢一個文件時,必須把與該文件的這兩部分資源一個不落地回收,回收方法為:
1、f.close() #回收操作系統級打開的文件
2、del f #回收應用程序級的變量

其中del f一定要發生在f.close()之后,否則就會導致操作系統打開的文件還沒有關閉,白白占用資源,
而python自動的垃圾回收機制決定了我們無需考慮del f,這就要求我們,在操作完畢文件后,一定要記住f.close()

雖然我這么說,但是很多同學還是會很不要臉地忘記f.close(),對於這些不長腦子的同學,我們推薦傻瓜式操作方式:使用with關鍵字來幫我們管理上下文
with open('a.txt','w') as f:
    pass
 
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
    data=read_f.read()
    write_f.write(data)
注意

文件編碼

 f=open(...)是由操作系統打開文件,那么如果我們沒有為open指定編碼,那么打開文件的默認編碼很明顯是操作系統說了算了,操作系統會用自己的默認編碼去打開文件,在windows下是gbk,在linux下是utf-8。

#這就用到了上節課講的字符編碼的知識:若要保證不亂碼,文件以什么方式存的,就要以什么方式打開。
f=open('a.txt','r',encoding='utf-8')

文件的打開模式

文件句柄 = open('文件路徑', '模式'

模式可以是以下方式以及他們之間的組合:

 

Character Meaning
‘r' open for reading (default)
‘w' open for writing, truncating the file first
‘a' open for writing, appending to the end of the file if it exists
‘b' binary mode
‘t' text mode (default)
‘+' open a disk file for updating (reading and writing)
‘U' universal newline mode (for backwards compatibility; should not be used in new code)

#1. 打開文件的模式有(默認為文本模式):
r ,只讀模式【默認模式,文件必須存在,不存在則拋出異常】
w,只寫模式【不可讀;不存在則創建;存在則清空內容】
a, 之追加寫模式【不可讀;不存在則創建;存在則只追加內容】

#2. 對於非文本文件,我們只能使用b模式,"b"表示以字節的方式操作(而所有文件也都是以字節的形式存儲的,使用這種模式無需考慮文本文件的字符編碼、圖片文件的jgp格式、視頻文件的avi格式)
rb 
wb
ab
注:以b方式打開時,讀取到的內容是字節類型,寫入時也需要提供字節類型,不能指定編碼
#"+" 表示可以同時讀寫某個文件
r+, 讀寫【可讀,可寫】
w+,寫讀【可讀,可寫】
a+, 寫讀【可讀,可寫】
x, 只寫模式【不可讀;不存在則創建,存在則報錯】
x+ ,寫讀【可讀,可寫】
xb
了解
由於歷史的原因,換行符在不同的系統中有不同模式,比如在 unix中是一個\n,而在windows中是‘\r\n’,用U模式打開文件,就是支持所有的換行模式,也就說‘\r’ '\n' '\r\n'都可表示換行
t是windows平台特有的所謂text mode(文本模式),區別在於會自動識別windows平台的換行符。
了解2
Files opened in binary mode (appending 'b' to the mode argument) return contents as bytes objects without any decoding.
b是以二進制的形式來讀文件,但是顯示出來的卻不是0101,而是以字節的形式顯示出來。
一個字節是8位二進制,所以計算機是自動幫你進行了轉換。
請不要誤會b模式是按照字節讀。
關於b模式讀文件

 

文件內的光標移動

一: read(3):

  1. 文件打開方式為文本模式時,代表讀取3個字符

  2. 文件打開方式為b模式時,代表讀取3個字節

二: 其余的文件內光標移動都是以字節為單位如seek,tell,truncate

注意:

  1. seek有三種移動方式0,1,2,其中1和2必須在b模式下進行,但無論哪種模式,都是以bytes為單位移動的

  2. truncate是截斷文件,所以文件的打開方式必須可寫,但是不能用w或w+等方式打開,因為那樣直接清空文件了,所以truncate要在r+或a或a+等模式下測試效果

 

 with上下文管理

打開一個文件包含兩部分資源:操作系統級打開的文件+應用程序的變量。在操作完畢一個文件時,必須把與該文件的這兩部分資源一個不落地回收,回收方法為:
1、f.close() #回收操作系統級打開的文件
2、del f #回收應用程序級的變量

其中del f一定要發生在f.close()之后,否則就會導致操作系統打開的文件還沒有關閉,白白占用資源,
而python自動的垃圾回收機制決定了我們無需考慮del f,這就要求我們,在操作完畢文件后,一定要記住f.close()

雖然我這么說,但是很多同學還是會很不要臉地忘記f.close(),對於這些不長腦子的同學,我們推薦傻瓜式操作方式:使用with關鍵字來幫我們管理上下文

with open('a.txt','w') as f:
    pass
 
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
    data=read_f.read()
    write_f.write(data)

 

文件的修改

文件的數據是存放於硬盤上的,因而只存在覆蓋、不存在修改這么一說,我們平時看到的修改文件,都是模擬出來的效果,具體的說有兩種實現方式:

方式一:將硬盤存放的該文件的內容全部加載到內存,在內存中是可以修改的,修改完畢后,再由內存覆蓋到硬盤(word,vim,nodpad++等編輯器)

import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    data=read_f.read() #全部讀入內存,如果文件很大,會很卡
    data=data.replace('alex','SB') #在內存中完成修改

    write_f.write(data) #一次性寫入新文件

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt') 
方法一

方式二:將硬盤存放的該文件的內容一行一行地讀入內存,修改完畢就寫入新文件,最后用新文件覆蓋源文件

import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    for line in read_f:
        line=line.replace('alex','SB')
        write_f.write(line)

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt') 
方法二

練習

1. 文件a.txt內容:每一行內容分別為商品名字,價錢,個數,求出本次購物花費的總錢數

apple 10 3

tesla 100000 1

mac 3000 2

lenovo 30000 3

chicken 10 3

2. 修改文件內容,把文件中的alex都替換成SB

函數

為什么要用函數

現在python屆發生了一個大事件,len方法突然不能直接用了。。。

然后現在有一個需求,讓你計算'hello world'的長度,你怎么計算?

這個需求對於現在的你其實不難,我們一起來寫一下。

s1 = "hello world"
length = 0
for i in s1:
    length = length+1

print(length)
for循環實現len功能

好了,功能實現了,非常完美。然后現在又有了一個需求,要計算另外一個字符串的長度,"hello eva".

於是,這個時候你的代碼就變成了這樣:

s1 = "hello world"
length = 0
for i in s1:
    length = length+1

print(length)

s2 = "hello eva"
length = 0
for i in s2:
    length = length+1

print(length)
for循環實現len功能2

這樣確實可以實現len方法的效果,但是總感覺不是那么完美?為什么呢?

首先,之前只要我們執行len方法就可以直接拿到一個字符串的長度了,現在為了實現相同的功能我們把相同的代碼寫了好多遍 —— 代碼冗余

其次,之前我們只寫兩句話讀起來也很簡單,一看就知道這兩句代碼是在計算長度,但是剛剛的代碼卻不那么容易讀懂 —— 可讀性差

print(len(s1))
print(len(s2))

我們就想啊,要是我們能像使用len一樣使用我們這一大段“計算長度”的代碼就好了。這種感覺有點像給這段代碼起了一個名字,等我們用到的時候直接喊名字就能執行這段代碼似的。要是能這樣,是不是很完美啊?

初識函數定義與調用

現在就教大家一個既能,讓你們把代碼裝起來。

def mylen():
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)
View Code

我們一起來分析一下這段代碼做了什么。

其實除了def這一行和后面的縮進,其他的好像就是正常的執行代碼。我們來執行一下,哦,好像啥也沒發生。

剛剛我們已經說過,這是把代碼裝起來的過程。你現在只會往里裝,還不會往出拿。那么應該怎么往出拿呢?我來告訴大家:

mylen()

是不是很簡單?是不是似曾相識?這就是代碼取出來的過程。剛剛我們就寫了一個函數,並且成功調用了它。

#函數定義
def mylen():
    """計算s1的長度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)

#函數調用  
mylen()
函數的定義和調用

總結一:

定義:def 關鍵詞開頭,空格之后接函數名稱和圓括號(),最后還有一個":"。

   def 是固定的,不能變,必須是連續的def三個字母,不能分開。。。它們要相親相愛的在一起。

   空格 為了將def關鍵字和函數名分開,必須空(四聲),當然你可以空2格、3格或者你想空多少都行,但正常人還是空1格。

   函數名:函數名只能包含字符串、下划線和數字且不能以數字開頭。雖然函數名可以隨便起,但我們給函數起名字還是要盡量簡短,並能表達函數功能

   括號:是必須加的,先別問為啥要有括號,總之加上括號就對了!

注釋:每一個函數都應該對功能和參數進行相應的說明,應該寫在函數下面第一行。以增強代碼的可讀性。

調用:就是 函數名() 要記得加上括號,好么好么好么。

函數的返回值

剛剛我們就寫了一個函數,這個函數可以幫助我們計算字符串的長度,並且把結果打印出來。但是,這和我們的len方法還不是太一樣。哪里不一樣呢?以前我們調用len方法會得到一個值,我們必須用一個變量來接收這個值。

str_len = len('hello,world')

這個str_len就是‘hello,world’的長度。那我們自己寫的函數能做到這一點么?我們也來試一下。

#函數定義
def mylen():
    """計算s1的長度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)

#函數調用
str_len = mylen()
print('str_len : %s'%str_len)
函數調用的結果

很遺憾,如果你執行這段代碼,得到的str_len 值為None,這說明我們這段代碼什么也沒有給你返回。

那如何讓它也想len函數一樣返回值呢?

#函數定義
def mylen():
    """計算s1的長度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    return length

#函數調用
str_len = mylen()
print('str_len : %s'%str_len)
View Code

我們只需要在函數的最后加上一個return,return后面寫上你要返回的值就可以了。

接下來,我們就來研究一下這個return的用法。

return關鍵字的作用

  return 是一個關鍵字,在pycharm里,你會看到它變成藍色了。你必須一字不差的把這個單詞給背下來。

  這個詞翻譯過來就是“返回”,所以我們管寫在return后面的值叫“返回值”

要研究返回值,我們還要知道返回值有幾種情況:分別是沒有返回值、返回一個值、返回多個值

沒有返回值

  不寫return的情況下,會默認返回一個None:我們寫的第一個函數,就沒有寫return,這就是沒有返回值的一種情況。 

#函數定義
def mylen():
    """計算s1的長度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)

#函數調用
str_len = mylen()
#因為沒有返回值,此時的str_len為None
print('str_len : %s'%str_len)
不寫return  

  只寫return,后面不寫其他內容,也會返回None,有的同學會奇怪,既然沒有要返回的值,完全可以不寫return,為什么還要寫個return呢?這里我們要說一下return的其他用法,就是一旦遇到return,結束整個函數。  

def ret_demo():
    print(111)
    return
    print(222)

ret = ret_demo()
print(ret)
只寫return

      return None:和上面的兩種情況一樣,我們一般不這樣寫。

def ret_demo():
    print(111)
    return None
    print(222)

ret = ret_demo()
print(ret)
return None

返回一個值

      剛剛我們已經寫過一個返回一個值的情況,只需在return后面寫上要返回的內容即可。  

#函數定義
def mylen():
    """計算s1的長度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    return length

#函數調用
str_len = mylen()
print('str_len : %s'%str_len)
返回一個值

  注意:return和返回值之間要有空格,可以返回任意數據類型的值

返回多個值

  可以返回任意多個、任意數據類型的值

def ret_demo1():
    '''返回多個值''' 
    return 1,2,3,4


def ret_demo2():
    '''返回多個任意類型的值'''
    return 1,['a','b'],3,4

ret1 = ret_demo1()
print(ret1)
ret2 = ret_demo2()
print(ret2)
返回多個值

  返回的多個值會被組織成元組被返回,也可以用多個值來接收

def ret_demo2():
    return 1,['a','b'],3,4

#返回多個值,用一個變量接收
ret2 = ret_demo2()
print(ret2)

#返回多個值,用多個變量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)

#用多個值接收返回值:返回幾個值,就用幾個變量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)
多個返回值的接收

 

  原因:  

>>> 1,2  #python中把用逗號分割的多個值就認為是一個元組。
(1, 2)
>>> 1,2,3,4
(1, 2, 3, 4)
>>> (1,2,3,4)
(1, 2, 3, 4)
#序列解壓一
>>> a,b,c,d = (1,2,3,4)
>>> a
1
>>> b
2
>>> c
3
>>> d
4
#序列解壓二
>>> a,_,_,d=(1,2,3,4)
>>> a
1
>>> d
4
>>> a,*_=(1,2,3,4)
>>> *_,d=(1,2,3,4)
>>> a
1
>>> d
4
#也適用於字符串、列表、字典、集合
>>> a,b = {'name':'eva','age':18} 
>>> a
'name'
>>> b
'age'
序列解壓擴展

 

函數的參數 

現在,我們已經把函數返回值相關的事情研究清楚了,我們自己已經完成了一個可以返回字符串長度的函數。但是現在這個函數還是不完美,之前我們使用len函數的時候得是length = len("hello world"),這樣我可以想計算誰就計算誰的長度。但是現在我們寫的這個函數,只能計算一個“hello world”的長度,換一個字符串好像就是不行了。這可怎么辦?

#函數定義
def mylen(s1):
    """計算s1的長度"""
    length = 0
    for i in s1:
        length = length+1
    return length

#函數調用
str_len = mylen("hello world")
print('str_len : %s'%str_len)
帶參數的函數

我們告訴mylen函數要計算的字符串是誰,這個過程就叫做 傳遞參數,簡稱傳參,我們調用函數時傳遞的這個“hello world”和定義函數時的s1就是參數

實參與形參

參數還有分別:

我們調用函數時傳遞的這個“hello world”被稱為實際參數,因為這個是實際的要交給函數的內容,簡稱實參。

定義函數時的s1,只是一個變量的名字,被稱為形式參數,因為在定義函數的時候它只是一個形式,表示這里有一個參數,簡稱形參。  

傳遞多個參數

參數可以傳遞多個,多個參數之間用逗號分割。

def mymax(x,y):
    the_max = x if x > y else y
    return the_max

ma = mymax(10,20)
print(ma)
傳遞多個參數

也正是因為需要傳遞多個參數、可以傳遞多個參數,才會有了后面這一系列參數相關的故事。。。

位置參數

  站在實參角度

    1.按照位置傳值

def mymax(x,y):
    #此時x=10,y=20
    the_max = x if x > y else y
    return the_max

ma = mymax(10,20)
print(ma)
按照位置傳參

    2.按照關鍵字傳值

def mymax(x,y):
    #此時x = 20,y = 10
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(y = 10,x = 20)
print(ma)
按照關鍵字傳參

    3.位置、關鍵字形式混着用

def mymax(x,y):
    #此時x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(10,y = 20)
print(ma)
位置、關鍵字混用傳參

      正確用法

      問題一:位置參數必須在關鍵字參數的前面

      問題二:對於一個形參只能賦值一次      

  站在形參角度

    位置參數必須傳值

def mymax(x,y):
    #此時x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

#調用mymax不傳遞參數
ma = mymax()
print(ma)

#結果
TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'
位置參數必須傳參

默認參數

    1.正常使用

      使用方法

      為什么要有默認參數:將變化比較小的值設置成默認參數

    2.默認參數的定義

def stu_info(name,sex = "male"):
    """打印學生信息函數,由於班中大部分學生都是男生,
        所以設置默認參數sex的默認值為'male'
    """
    print(name,sex)


stu_info('alex')
stu_info('eva','female')
默認參數

    3.參數陷阱:默認參數是一個可變數據類型

def defult_param(a,l = []):
    l.append(a)
    print(l)

defult_param('alex')
defult_param('egon')
參數陷阱

 

動態參數

  按位置傳值多余的參數都由args統一接收,保存成一個元組的形式

def mysum(*args):
    the_sum = 0
    for i in args:
        the_sum+=i
    return the_sum

the_sum = mysum(1,2,3,4)
print(the_sum)
*args求和函數應用
def stu_info(**kwargs):
    print(kwargs)
    print(kwargs['name'],kwargs['sex'])

stu_info(name = 'alex',sex = 'male')
**kwargs應用  

  實際開發中:

  未來還會用到的場景。。。

  問題:

    位置參數、默認參數、動態參數定義的順序以及接收的結果?

參數總結:

命名空間和作用域

命名空間的本質:存放名字與值的綁定關系

>>> import this
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!
python之禪

在python之禪中提到過:命名空間是一種絕妙的理念,讓我們盡情的使用發揮吧!

 

命名空間一共分為三種:

  全局命名空間

  局部命名空間

  內置命名空間

*內置命名空間中存放了python解釋器為我們提供的名字:input,print,str,list,tuple...它們都是我們熟悉的,拿過來就可以用的方法。

三種命名空間之間的加載與取值順序:

加載順序:內置命名空間(程序運行前加載)->全局命名空間(程序運行中:從上到下加載)->局部命名空間(程序運行中:調用時才加載)

取值:

  在局部調用:局部命名空間->全局命名空間->內置命名空間

x = 1
def f(x):
    print(x)

print(10)
在局部使用變量取值情況

  在全局調用:全局命名空間->內置命名空間

x = 1
def f(x):
    print(x)

f(10)
print(x)
在全局引用變量x
print(max)
在全局引用內置max

作用域

作用域就是作用范圍,按照生效范圍可以分為全局作用域和局部作用域。

全局作用域:包含內置名稱空間、全局名稱空間,在整個文件的任意位置都能被引用、全局有效

局部作用域:局部名稱空間,只能在局部范圍生效

globals和locals方法

print(globals())
print(locals())
在全局調用globals和locals
def func():
    a = 12
    b = 20
    print(locals())
    print(globals())

func()
在局部調用globals和locals

global關鍵字

a = 10
def func():
    global a
    a = 20

print(a)
func()
print(a)
global關鍵字

 

函數的嵌套和作用域鏈

  函數的嵌套調用

def max2(x,y):
    m  = x if x>y else y
    return m

def max4(a,b,c,d):
    res1 = max2(a,b)
    res2 = max2(res1,c)
    res3 = max2(res2,d)
    return res3

# max4(23,-7,31,11)
函數的嵌套調用

  函數的嵌套定義

def f1():
    print("in f1")
    def f2():
        print("in f2")

    f2()
f1()
函數的嵌套定義(一)
def f1():
    def f2():
        def f3():
            print("in f3")
        print("in f2")
        f3()
    print("in f1")
    f2()
    
f1()
函數的嵌套定義(二) 

   函數的作用域鏈

def f1():
    a = 1
    def f2():
        print(a)
    f2()

f1()
作用域鏈(一)
def f1():
    a = 1
    def f2():
        def f3():
            print(a)
        f3()
    f2()

f1()
作用域鏈(二)
def f1():
    a = 1
    def f2():
        a = 2
    f2()
    print('a in f1 : ',a)

f1()
作用域鏈(三)

    nonlocal關鍵字

# 1.外部必須有這個變量
# 2.在內部函數聲明nonlocal變量之前不能再出現同名變量
# 3.內部修改這個變量如果想在外部有這個變量的第一層函數中生效
def f1():
    a = 1
    def f2():
        nonlocal a
        a = 2
    f2()
    print('a in f1 : ',a)

f1()
nonlocal關鍵字
 
 

函數小結

面向過程編程的問題:代碼冗余、可讀性差、可擴展性差(不易修改)

定義函數的規則:

1.定義:def 關鍵詞開頭,空格之后接函數名稱和圓括號()。
2.參數:圓括號用來接收參數。若傳入多個參數,參數之間用逗號分割。
    參數可以定義多個,也可以不定義。
    參數有很多種,如果涉及到多種參數的定義,應始終遵循位置參數、*args、默認參數、**kwargs順序定義。
    如上述定義過程中某參數類型缺省,其他參數依舊遵循上述排序 3.注釋:函數的第一行語句應該添加注釋。 4.函數體:函數內容以冒號起始,並且縮進。 5.返回值:return [表達式] 結束函數。不帶表達式的return相當於返回 None def 函數名(參數1,參數2,*args,默認參數,**kwargs): """注釋:函數功能和參數說明""" 函數體 …… return 返回值

調用函數的規則:

1.函數名()
    函數名后面+圓括號就是函數的調用。 2.參數: 圓括號用來接收參數。 若傳入多個參數: 應按先位置傳值,再按關鍵字傳值 具體的傳入順序應按照函數定義的參數情況而定 3.返回值 如果函數有返回值,還應該定義“變量”接收返回值 如果返回值有多個,也可以用多個變量來接收,變量數應和返回值數目一致 無返回值的情況: 函數名() 有返回值的情況: 變量 = 函數名() 多個變量接收多返回值: 變量1,變量2,... = 函數名()

  

命名空間:

  一共有三種命名空間從大范圍到小范圍的順序:內置命名空間、全局命名空間、局部命名空間

作用域(包括函數的作用域鏈):

小范圍的可以用大范圍的
但是大范圍的不能用小范圍的
范圍從大到小(圖) 

練習題

1、任一個英文的純文本文件,統計其中的每個單詞出現的個數,注意是每個單詞。。

2、寫函數,計算傳入數字參數的和。(動態傳參)

3、寫函數,用戶傳入修改的文件名,與要修改的內容,執行函數,完成整個文件的批量修改操作

4、寫函數,檢查用戶傳入的對象(字符串、列表、元組)的每一個元素是否含有空內容。

5、寫函數,檢查傳入字典的每一個value的長度,如果大於2,那么僅保留前兩個長度的內容(對value的值進行截斷),並將新內容返回給調用者,注意傳入的數據可以是字符、list、dict

6、寫函數,返回一個撲克牌列表,里面有52項,每一項是一個元組

 

  例如:[(‘紅心’,2),(‘草花’,2), …(‘黑桃A’)]

 

7、寫函數,傳入n個數,返回字典{‘max’:最大值,’min’:最小值}

  例如:minmax(2,5,7,8,4)
  返回:{‘max’:8,’min’:2}

8、寫函數,專門計算圖形的面積

 

  • 其中嵌套函數,計算圓的面積,正方形的面積和長方形的面積
  • 調用函數area(‘圓形’,圓半徑) 返回圓的面積
  • 調用函數area(‘正方形’,邊長) 返回正方形的面積
  • 調用函數area(‘長方形’,長,寬) 返回長方形的面積
#代碼模板
def area():
def 計算長方形面積():
pass

def 計算正方形面積():
pass

def 計算圓形面積():
pass

 

9、寫函數,傳入一個參數n,返回n的階乘

  例如:cal(7)
  返回計算7*6*5*4*3*2*1的結果

 

10、如下,每個小字典的name對應股票名字,shares對應多少股,price對應股票的價格

portfolio = [
{‘name’: ‘IBM’, ‘shares’: 100, ‘price’: 91.1},
{‘name’: ‘AAPL’, ‘shares’: 50, ‘price’: 543.22},
{‘name’: ‘FB’, ‘shares’: 200, ‘price’: 21.09},
{‘name’: ‘HPQ’, ‘shares’: 35, ‘price’: 31.75},
{‘name’: ‘YHOO’, ‘shares’: 45, ‘price’: 16.35},
{‘name’: ‘ACME’, ‘shares’: 75, ‘price’: 115.65}
]
  • 通過哪個內置函數可以計算購買每支股票的總價
  • 用filter過濾出,單價大於100的股票有哪些


11、有列表 li = [‘alex’, ‘egon’, ‘smith’, ‘pizza’, ‘alen’], 請將以字母“a”開頭的元素的首字母改為大寫字母;

 

12、有列表 li = [‘alex’, ‘egon’, ‘smith’, ‘pizza’, ‘alen’], 請以列表中每個元素的第二個字母倒序排序;

 

13、有名為poetry.txt的文件,其內容如下,請刪除第三行;

昔人已乘黃鶴去,此地空余黃鶴樓。

黃鶴一去不復返,白雲千載空悠悠。

晴川歷歷漢陽樹,芳草萋萋鸚鵡洲。

日暮鄉關何處是?煙波江上使人愁。

 

14、有名為username.txt的文件,其內容格式如下,寫一個程序,判斷該文件中是否存在”alex”, 如果沒有,則將字符串”alex”添加到該文件末尾,否則提示用戶該用戶已存在;

pizza
alex
egon

 

15、有名為user_info.txt的文件,其內容格式如下,寫一個程序,刪除id為100003的行;

pizza,100001
alex, 100002
egon, 100003

 

16、有名為user_info.txt的文件,其內容格式如下,寫一個程序,將id為100002的用戶名修改為alex li

pizza,100001
alex, 100002
egon, 100003

 

作業

1.股票查詢程序開發

把以下股票數據存入stock_data.txt



數據來源:東方財富網


開發程序對stock_data.txt進行以下操作:

1.程序啟動后,給用戶提供查詢接口,允許用戶重復查股票行情信息(用到循環)

2.允許用戶通過模糊查詢股票名,比如輸入“啤酒”, 就把所有股票名稱中包含“啤酒”的信息打印出來

3.允許按股票價格、漲跌幅、換手率這幾列來篩選信息,比如輸入“價格>50”則把價格大於50的股票都打印,輸入“市盈率<50“,則把市盈率小於50的股票都打印,不用判斷等於。

思路提示:加載文件內容到內存,轉成dict or list結構,然后對dict or list 進行查詢等操作。 這樣以后就不用每查一次就要打開一次文件了,效率會高。

程序啟動后執行效果參考:

 1 股票查詢接口>>:換手率>25
 2 ['序號', '代碼', '名稱', '最新價', '漲跌幅', '漲跌額', '成交量(手)', '成交額', '振幅', '最高', '最低', '今開', '昨收', '量比', '換手率', '市盈率', '市凈率']
 3 ['18', '603697', '有友食品', '22.73', '10.02%', '2.07', '34.93萬', '7.68億', '8.23%', '22.73', '21.03', '21.17', '20.66', '1.4', '43.94%', '38.1', '4.66'] 4 ['23', '603956', '威派格', '22.52', '10.01%', '2.05', '18.33萬', '4.01億', '10.60%', '22.52', '20.35', '20.35', '20.47', '2.16', '43.02%', '-', '9.82'] 5 ['36', '300748', '金力永磁', '59.7', '10.01%', '5.43', '11.02萬', '6.38億', '6.98%', '59.7', '55.91', '56.88', '54.27', '0.9', '26.49%', '234.09', '23.54'] 6 ['37', '300767', '震安科技', '41.13', '10.00%', '3.74', '6.22萬', '2.49億', '10.32%', '41.13', '37.27', '37.48', '37.39', '3.86', '31.11%', '43.32', '3.68'] 7 ['38', '603045', '福達合金', '32', '10.00%', '2.91', '17.06萬', '5.31億', '9.87%', '32', '29.13', '29.13', '29.09', '1.39', '25.17%', '52.74', '4.02'] 8 ['39', '2952', '亞世光電', '58.98', '10.00%', '5.36', '4.18萬', '2.41億', '7.42%', '58.98', '55', '55.91', '53.62', '3.04', '27.44%', '53.09', '5.51'] 9 找到6條 10 股票查詢接口>>:最新價<5 11 ['序號', '代碼', '名稱', '最新價', '漲跌幅', '漲跌額', '成交量(手)', '成交額', '振幅', '最高', '最低', '今開', '昨收', '量比', '換手率', '市盈率', '市凈率'] 12 ['2', '2676', '順威股份', '3.69', '10.15%', '0.34', '15.23萬', '5516萬', '9.55%', '3.69', '3.37', '3.37', '3.35', '1.16', '2.11%', '-', '2.58'] 13 ['3', '601619', '嘉澤新能', '4.91', '10.09%', '0.45', '16.55萬', '8006萬', '8.52%', '4.91', '4.53', '4.54', '4.46', '1.82', '3.28%', '52.26', '3.64'] 14 找到2條 15 股票查詢接口>>:食品 16 ['18', '603697', '有友食品', '22.73', '10.02%', '2.07', '34.93萬', '7.68億', '8.23%', '22.73', '21.03', '21.17', '20.66', '1.4', '43.94%', '38.1', '4.66'] 17 找到1條 18 股票查詢接口>>:能源 19 ['9', '2828', '貝肯能源', '14.25', '10.04%', '1.3', '17.83萬', '2.52億', '4.71%', '14.25', '13.64', '13.8', '12.95', '3.45', '18.03%', '-', '3.08'] 20 找到1條 21 股票查詢接口>>:科技 22 ['12', '2866', '傳藝科技', '13.81', '10.04%', '1.26', '13.59萬', '1.83億', '9.72%', '13.81', '12.59', '12.61', '12.55', '2.63', '16.86%', '33.37', '3.43'] 23 ['19', '300777', '中簡科技', '24.92', '10.02%', '2.27', '5952', '1483萬', '0.00%', '24.92', '24.92', '24.92', '22.65', '3.45', '1.49%', '102.24', '11.49'] 24 ['21', '300245', '天璣科技', '11.53', '10.02%', '1.05', '26.86萬', '3.05億', '9.64%', '11.53', '10.52', '10.52', '10.48', '1.06', '10.35%', '127.47', '2.57'] 25 ['26', '300391', '康躍科技', '7.8', '10.01%', '0.71', '3.9萬', '3027萬', '10.01%', '7.8', '7.09', '7.09', '7.09', '0.75', '1.94%', '27.35', '1.89'] 26 ['37', '300767', '震安科技', '41.13', '10.00%', '3.74', '6.22萬', '2.49億', '10.32%', '41.13', '37.27', '37.48', '37.39', '3.86', '31.11%', '43.32', '3.68'] 27 ['40', '603327', '福蓉科技', '21.56', '10.00%', '1.96', '3586', '773.1萬', '0.00%', '21.56', '21.56', '21.56', '19.6', '2.81', '0.70%', '31.97', '8.05'] 28 找到6條 

 

2.遞歸二分查找

https://www.cnblogs.com/Eva-J/articles/7197403.html根據博客學習二分查找算法。

並自己找一個遞歸相關的練習題進行練習,上交題目和代碼。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM