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

1.深淺拷貝python

  在Python中將一個變量的值傳遞給另一個變量一般有三種:賦值、淺拷貝、深拷貝git

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

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

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

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內存地址的表達方式)都是同樣的ssh

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

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

  賦值是將變量的內存賦給另外一個變量,讓另外一個變量指向那個內存地址ui

 

  淺拷貝編碼

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


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'], key = lambda x: x.lower()))#['A', 'b', 'C']

print(sorted(['A', 'b', 'C'], key = lambda x: x.lower(), reverse = True))
#['C', 'b', 'A']

#對一個序列對象進行排序,key接收一個函數,將序列的每個函數處理返回的結果做爲排序的依據,好比字符串都轉換成小寫排序或字典按照key或value排序等,reverse表示對排序的結果是否排序,默認字符串是先大寫後小寫的順序排序的
sorted(iterable[, key][, reverse])
print(str('abc'))    #'abc'

print(str(1234))    #'1234'

#建立一個字符串對象,或者將一個對象轉化爲字符串對象
class str(object='')
print(sum([1, 2, 4]))    #7

print(sum([1, 2, 4], 1))    #8

#返回一個序列對象的相加的總和在加上start,start默認是0,序列對象要麼全是數字要麼都是字符串,字符串就至關於把它們都拼接在一塊兒
sum(iterable[, start])
print(tuple())    #()

print(tuple([1, 2, 4]))    #(1, 2, 4)

#建立一個元組對象,或將一個對象轉化爲元組
tuple([iterable])
print(type(1))    #<class 'int'>

'''
class type(object)
class type(name, bases, dict)
返回一個對象的類型
'''
type
import sys

vars(sys)
#{'version_info': sys.version_info(major=3, minor=4, micro=0, releaselevel='final', serial=0), 'getswitchinterval': <built-in function getswitchinterval>, '__name__': 'sys', 'path_hooks': [<class 'zipimport.zipimporter'>, <function FileFinder.path_hook.<locals>.path_hook_for_FileFinder at 0x7fcc97b51ae8>],後面省略n多行

#返回模塊,類,實例或者任何其餘有__dict__屬性的對象的__dict__屬性,默認是顯示當前環境的
vars([object])
x = [1, 2, 3, 4]
y = ['a', 'b', 'c']
print(zip(x, y))    #<zip object at 0x7fcc954aea08>
print(list(zip(x, y)))    #[(1, 'a'), (2, 'b'), (3, 'c')]


#將多個元素組成一個新的zip對象,zip對象的元素個數取決於元素最少的參數
zip(*iterables)
相關文章
相關標籤/搜索