python基礎(7)--深淺拷貝、函數

来源:http://www.cnblogs.com/caoj/archive/2017/11/20/7868844.html
-Advertisement-
Play Games

1.深淺拷貝 在Python中將一個變數的值傳遞給另外一個變數通常有三種:賦值、淺拷貝、深拷貝 Python數據類型可氛圍基本數據類型包括整型、字元串、布爾及None等,還有一種由基本數據類型作為最基本的元素所組成的像列表、元組、字典等。 在Python中基本數據類型的賦值、深淺拷貝沒有任何意義,都 ...


1.深淺拷貝

  在Python中將一個變數的值傳遞給另外一個變數通常有三種:賦值、淺拷貝、深拷貝

  Python數據類型可氛圍基本數據類型包括整型、字元串、布爾及None等,還有一種由基本數據類型作為最基本的元素所組成的像列表、元組、字典等。

  在Python中基本數據類型的賦值、深淺拷貝沒有任何意義,都是指向同一塊記憶體地址,也不存在層次問題。

  下麵看基本數據類型的深淺拷貝

import copy
n1 = 'abc'
n2 = n1
n3 = copy.copy(n1)
n4 = copy.deepcopy(n1)
print(id(n1))    #輸出140350336680040
print(id(n2))    #輸出140350336680040
print(id(n3))    #輸出140350336680040
print(id(n4))    #輸出140350336680040

  以上代碼說明Python的copy模塊的copy和deepcopy函數實現了淺拷貝和深拷貝,可以看到,賦值、淺拷貝和深拷貝最後的id(Python記憶體地址的表達方式)都是一樣的

  接下來討論其他的列表、元組、字典等非基本數據類型對象的賦值、深淺拷貝的區別

  假設字典n1 = {"k1": "abc", "k2": 123, "k3": ["abc", 123]} 

  賦值是將變數的記憶體賦給另一個變數,讓另一個變數指向那個記憶體地址

 

  淺拷貝

  淺拷貝就是在記憶體中將第一層額外開闢空間進行存放


n1 = {"k1": "abc", "k2": 123, "k3": ["abc", 123]}   
print(id(n1))    #140350328984328
n3 = copy.copy(n1)
print(id(n3))    #140350328986504可以看n3的記憶體地址已經和n1不同了


print(id(n1['k3']))    #140350328603976
print(id(n3['k3']))    #140350328603976 字典里的列表還是指向同一個列表

  深拷貝

  深拷貝就是在記憶體中將數據重新創建一份,不僅僅是第一層,第二層、第三層...都會重新創建


 

 

n1 = {"k1": "abc", "k2": 123, "k3": ["abc", 123]}
print(id(n1))    #140350328984328
n3 = copy.deepcopy(n1)

print(id(n1['k3']))    #140350328603976
print(id(n3['k3']))    #140350328604296 #可以看到第二層的列表也拷貝了一份,記憶體地址已經完全不一樣

#註意,這僅局限於非基本數據類型,基本數據類型還是同一個記憶體地址

 

 

2.函數

  函數的定義及調用

  定義一個函數要使用def關鍵字,依次寫出函數名、括弧、括弧中的參數和冒號:,然後用縮進的代碼塊寫函數體,函數體內可以調用return語句返回結果。

  函數名作為函數的名稱,也可以像變數一樣進行賦值操作、甚至作為參數進行傳遞。

  

  函數的參數

  1)位置參數

  這是最常見的定義方式,一個函數可以定義任意個參數,每個參數用逗號分隔,例如:

def Foo1(arg1, arg2):
    print(arg1, arg2)

  用這種方式定義的函數在調用的的時候也必須在函數名後的小括弧里提供個數相等的值(實際參數),而且順序必須相同,也就是說在這種調用中,形參和實參的個數必須一致,而且必須一一對應,也就是說第一個形參對應這第一個實參。例如:

Foo1('abc', 123)
#輸出結果 abc 123

  也可以通過如下方式傳遞參數,而不必考慮順序問題,但數量無論如何必須一致。

foo3(arg2 = 123, arg1 = 'abc')

 

  2)預設參數

  我們可以給某個參數指定一個預設值,當調用時,如果沒有指定那個參數,那個參數就等於預設值

def Foo2(arg1, arg2 = 123):
     print(arg1, arg2)

  調用

Foo2('abc')
Foo2('abc', 345)

'''
執行結果 
    abc 123
    abc 345    
註意:定義的時候預設參數必須放到所有位置參數的後面進行定義,否則會報語法錯誤 
'''

  

  3)可變參數

  可變參數就是傳入的參數個數是可變的,也可以是0個,例如

def Foo3(*args):
     print(args)

  調用

Foo3(1, 2, 'abc')

#執行結果  (1, 2, 'abc')  可以看到我們傳遞了三個參數都被Python轉化為元祖,保存到args中了,這樣我們就可以通過索引對參數記性調用,或者通過for in進行遍歷

  

  4)關鍵字參數

  可變參數在調用過程中會組裝成元組,元組只能通過索引進行調用,有時不是很方便,故Python可以通過關鍵字索引將傳入的參數組裝成字典

  

def Foo4(**kwargs):
    print(kwargs, type(kwargs))

Foo4(k1 = 'abc', k2 = 123)


#執行結果 {'k2': 123, 'k1': 'abc'} <class 'dict'>
#關鍵字參數允許傳入0個或任意個參數名的參數,0個的話就是一個空字典

 

 

  參數組合

  在Python中定義函數,可以用必選參數(位置參數)、預設參數、可變參數、關鍵字參數這幾種參數進行組合使用,但是順序必須是,必選參數、預設參數、可變參數、關鍵字參數。

def Foo5(arg1, arg2='abc', *args, **kwargs):
    print('arg1:', arg1)
    print('arg2:', arg2)
    print('args', args)
    print('kwargs', kwargs)

Foo5(123, 'abc', 456, 'def', k1=123, k2='abc')


'''
執行結果
arg1: 123
arg2: abc
args (456, 'def')
kwargs {'k1': 123, 'k2': 'abc'}

'''

 

  lambda匿名函數

  匿名函數就是功能非常簡單隻需要一行代碼就可以實現的,例如,求圓形面積

f = lambda r: 3.14 * r * r
print(f(4)) # 輸出 50.24

#r相當於匿名函數的參數,當然也可以有多個參數,不用在寫return,表達式就是返回的結果。

  使用匿名函數有個好處,因為函數沒有名字,不用擔心函數名衝突,此外匿名函數也是一個函數對象,也可以把匿名函數賦值給一個變數,再利用變數調用該函數。

  

  關於函數的return語句

  1)函數可以沒有return語句,沒有就預設返回None

  2)return語句有點類似迴圈的break,當函數執行到return語句時候,直接跳出函數的執行

  3)return可以返回多個值,多個值可以用兩個變數接收,也可以額一個變數接收

def Foo6():
    return 123, 'abc'

res1, res2 =Foo6()
print('res1:', res1)    #res1: 123
print('res2:', res2)    #res2: abc

res = Foo6()
print('res:', res)  #res: (123, 'abc')

#返回多個值就是返回一個元組,使用兩個變數接收的時候回將元組的元素與變數一一對應賦給多個變數

 

  關於可變參數和關鍵字參數的傳遞小技巧

  我們已經知道可變參數和關鍵字參數分別將傳遞的參數組裝成元組和字典,那麼我們同樣可以直接將元組、列表和字典直接傳遞給函數作為參數,傳遞的時候列表和元組要在變數前面加一個*,字典要在前面加兩個*,否則函數還是會把它們當成一個普通的參數傳遞進行處理

def Foo7(*args, **kwargs):
    print(args)
    print(kwargs)

li = [1, 2, 3]
dic = {'k':1, 'k2':2}
Foo7(li, dic)
Foo7(*li, **dic)

'''
執行結果
([1, 2, 3], {'k': 1, 'k2': 2})
{}    #可以看到兩個參數都被可變參數接收了,關鍵字參數啥也沒有
(1, 2, 3)
{'k': 1, 'k2': 2}

'''

 

 

  Python常用的內置函數


 

  只重點關註標記的內置函數

print(abs(-10))

#輸出10
abs 返回絕對值
print(all([1, True, 1 == 1]))

#True
all 可迭代對象(列表、元祖等)中所有的元素都是True,則返回True,否則返回False。相當於and
print(any([None, "", [], (), {}, 0, False])) #False

print(any([None, "", [], (), {}, 0, True]) )#True

#通常情況下“空”(None,空字元串、空列表,0等等)都是表示False
any 相當於or
print(bin(10))

#'0b1010'
bin 整數轉換二進位字元串
print(bool())  #False

print(bool(10))  #True
class bool 返回或者新建一個布爾值
print(chr(89999))    #'\U00015f8f'

print(chr(97))    #'a'
chr 整數轉成unicode編碼所對應的位元組
print(dict())    #{}

print(dict(k1 = 'v1', k2 = 'v2'))    #{'k1': 'v1', 'k2': 'v2'}

print(dict((['k1', 'v1'], ['k2', 'v2'])))    #{'k1': 'v1', 'k2': 'v2'}

print(dict({'k1':'v1', 'k2':'v2'}))    #{'k1': 'v1', 'k2': 'v2'}
dict 創建字典對象
print(dir(""))

#['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
dir 查看所有變數名和方法名
print(divmod(10, 3))

#(3, 1)    返回兩個數的得商和餘數組成的元組,相當於(a // b, a % b)
divmod返回兩個數的得商和餘數組成的元組
enu = enumerate(['abc', 'def', 'ghi'])
print(enu)
for i in enu
    print(i)

'''
返回一個迭代器,每次迭代返回一個元組包括一個計數器,和對iterable迭代取得的值,iterable可迭代對象,包括列表、元祖等。start表示計數器的開始值,預設是0
執行結果
<enumerate object at 0x0000000BE2D53510> # 可以看到返回的是一個enumerate對象
(0, 'abc')
(1, 'def')
(2, 'ghi')
'''

#註意:返回的是是一個迭代器,迭代完了空了,如果需要重覆使用,最好轉化為一個列表對象保存到變數中,並且計數器是從0開始計數的
li = list(enumerate(['abc', 'def', 'ghi']))
print(li)     #[(0, 'abc'), (1, 'def'), (2, 'ghi')]

#還可以指定start的開始值
li = list(enumerate(['abc', 'def', 'ghi'], 2))
print(li)    #[(2, 'abc'), (3, 'def'), (4, 'ghi')]
enumerate(iterable, start=0)
print(eval('3 + 4 * (1 - 3)'))   #-5


#將的字元串形式的算數表達式進行計算,並返回結果
eval(expression, globals=None, locals=None)
def func(num):
    if num % 2 ==0:
        return True
    else:
        return False

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

print(list(filter(func, nums)))


'''
接收一個函數和一個可迭代對象,將可迭代對象的每一個元素都作為參數執行函數,函數返回為真的放到一個新的可迭代對象中,並將新的可迭代對象返回


執行結果
[2, 4, 6, 8, 10, 12, 14, 16, 18]
'''
filter(function, iterable)
print('0.5')    #0.5

print(0.5)    #0.5

#創建一個浮點類型的對象
class float([x])
#返回某個對象的幫助信息
help([object])
print(hex(23))    #'0x17'

#返回一個整數的16進位表達式
hex(x)
print(id(1))    #10455040
#返回對象的id(可以理解為Python為每個對象的編號,或者理解為是Python對象記憶體地址的表達形式)
id(object)
s = input('python>>')

print(s)

'''
輸入123
輸出'123'

接受用戶從控制台的輸入,並將用戶輸入的信息,以字元串的返回,prompt表示輸入時前顯示的字元串
'''
input([prompt])
print(int())    #0

print(int('1010', base=2))    #10

#創建一個整數類型的對象,預設如果創建的0,如果傳遞的是字元串類型的,可以把字元串表達式所表示的整數轉化為整數類型,base表示的傳遞的字元串進位,預設是十進位
class int(x=0)
print(len('abc'))    #3

#返回一個對象的長度(或者元素的個數)
#所謂的長度一般隻字符串,像整數、浮點數等數據類型沒有len方法
len(s)
print(list([1, 2, 3]))    #[1, 2, 3]
prnt(list({'k1':'v1', 'k2':'v2'}))    #['k2', 'k1']

#將一個可迭代對象轉化為列表
#可以看到字典只是把key組成了列表,因為字典真正迭代的是key,value只是與key對應而已
class list([iterable])
s = map(lambda x: x**2, [1, 2, 3])
print(s)    #<map object at 0x0000000002D14CF8>

l = list(map(lambda x: x**2, [1, 2, 3]))
print(l)       #[1, 4, 9]

#接收一個函數和一個可迭代對象,將可迭代對象里的每一個元素都做作為參數傳遞到函數中,並把函數的返回結果保存到一個map對象中
#函數可以是匿名函數,另外函數必須有返回值,如果沒有返回值,雖然不會報錯,但沒有任何意義,例如
map(function, iterable, ...)
print(max(1, 2, 3))    #3

'''
max(iterable, *[, key, default])
max(arg1, arg2, *args[, key])
返回可迭代對象中(或者2個以上參數中)最大的值

'''
max
print(min(1, 2, 3))    #1

'''
min(iterable, *[, key, default])
min(arg1, arg2, *args[, key])
返回可迭代對象中(或者2個以上參數中)最大的值
'''
min
print(oct(9))    #'0o11'

#將一個數轉化為8進位的表達形式    Python中0o表示8進位
oct(x)
'''
    open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

  打開文件並返迴文件文件對象,file表示文件名(可以是絕對路徑,也可以是相對路徑),mode表示打開方式,預設的是rt模式,表示只讀的文本格式

'''
open
print(ord('a'))    #97

#返回一個字元的Unicode編碼
ord(c)
print(pow(2, 3)  )    #8

print(pow(2, 3, 3))    #2

#如果只傳遞兩個參數x和y,就計算x的y次方,相當於x ** y
#參數z表示將x ** y的結果對z取模,相當於x ** y % z
pow(x,y[,z])
'''
    print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

  列印函數,object表示要輸出的對象,sep表示多個對象之間的分隔符,預設是空格,end表示末尾的字元,預設是回車符,file表示輸出的文件,預設為sys.stdout也就是終端(標準輸出)
'''
print
print(list(range(1, 10)))    #[1, 2, 3, 4, 5, 6, 7, 8, 9]

print(list(range(1, 10, 2)))    #[1, 3, 5, 7, 9]

print(list(range(5))    #[0, 1, 2, 3, 4]

'''
range(stop)
range(start, stop[, step])
生成大於等於start,小於stop步長為step的數字序列,start預設是0
'''
range
print(reversed([0, 1, 2, 3, 4]))    #<list_reverseiterator object at 0x7fcc954acd68>

print(list(reversed([0, 1, 2, 3, 4])))    #[4, 3, 2, 1, 0]

#翻轉一個序列,序列對象必須是有序的,也就是對象必須包含__reversed__()方法
reversed(seq)
print(round(1.236, 2))    #1.24

print(round(1.2, 2))    #1.2

#返回一個浮點數的後面保留ndigits位小數的結果,四捨五入,小數點位數不足,不補0
round(number[, ndigits])
print(set(1, 2, 4, 2))    #{1, 2, 4}

#根據序列對象創建集合對象
class set([iterable])
print(sorted(['A', 'b', 'c']))    #['A', 'b', 'c']

print(sorted(['A', 'b', 'C']))    #['A', 'C', 'b']

print(sorted(['A', 'b', 'C'], k

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 演示產品下載地址:http://www.jinhusns.com ...
  • 下載地址:http://ilspy.net/ 中文版下載地址:http://www.fishlee.net/soft/ilspy_chs 對dll和exe文件反編譯: ...
  • 在Winform開發中,我們往往除了常規的單表信息錄入外,有時候設計到多個主從表的數據顯示、編輯等界面,單表的信息一般就是控制項和對象實體一一對應,然後調用API保存即可,主從表就需要另外特殊處理,本隨筆介紹如何快速實現主從表編輯界面的處理,結合GridControl控制項的GridView控制項對象,實... ...
  • 為了防止不提供原網址的轉載,特在這裡加上原文鏈接: "http://www.cnblogs.com/skabyy/p/7695258.html" 本篇將實現登錄、許可權控制、日誌配置與審計日誌的功能。首先我們先實現登錄功能,在登錄的基礎上,通過控權使得只有ID為1988的用戶才能創建tweet。最後配 ...
  • 返回總目錄 本小節目錄 Split Temporary Variable(分解臨時變數) Remove Assignments to Parameters(移除對參數的賦值) Remove Assignments to Parameters(移除對參數的賦值) 6 Split Temporary V ...
  • sae中安裝有python環境,想讓sae導入自己下載的django或者其他模塊,可以在svn中新建一個文件目錄,比如site-packages,跟python安裝目錄一樣,這個目錄存放所有的python模塊(包括django),將安裝目錄下的以及用pip install安裝的各種模塊copy入這個 ...
  • 本文主要介紹JDK環境配置、Sublime Text3配置及第一個HelloWorld.Java程式。運行環境為Win10系統,使用JDK1.8版本。 ...
  • VS2008創建MFC程式 1. 點擊菜單欄 文件 新建 項目 選擇MFC應用程式 MFC ActiveX 控制項用來生成MFC ActiveX控制項程式。 MFC應用程式用來生成MFC應用程式。 MFC DLL用來生成MFC動態鏈接庫程式。 2. 填好項目名稱,存儲位置後點擊確定進入MFC應用程式嚮導 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...