python基礎學習day6

代碼塊、緩存機制、深淺拷貝、集合html

  • id、is、==
  1. id: 可類比爲身份號,具備惟一性,若id 相同則爲同一個數據。
#獲取數據的內存地址(隨機的地址:內存臨時加載,存儲數據,當程序運行結束後,內存地址即被丟棄):
i = 'a'
print(id(i))
>>>2047746570672  
print(id(i))
>>>2020558633392
print(id(i))
print(id(i))
>>>1908036008368
1908036008368

l1 = [1,2,3]
l2 = [1,2,3]
print(l1 == l2)
>>>True    #比較的是兩邊的值是否相等。
  1. is 判斷id是否相同 (‘’==’‘判斷值是否相同
l1 = [1,2,3]
l2 = [1,2,3]
print(l1 is l2)
>>>False   #判斷的是內存地址是否相同。

print(id(l1))
print(id(l2))
>>>2648963830216
2648963830728

l1 = [1,2,3]
l2 = l1
print(l1 is l2)
print(id(l1))
print(id(l2))
>>>True
2053863395784
2053863395784


s1 = 'iam'
s2 = 'iam'
print(s1 is s2)
>>>True

print(id(s1))
print(id(s2))
>>>2188534085552
2188534085552

​ id相同,值必定相同,值相同,id不必定相同。python

  • 代碼塊:python的程序是由代碼塊構造的。塊是一個python程序的腳本,它是做爲一個單元執行的。一個模塊,一個函數,一個類,一個文件等都是代碼塊。而做爲互交命令方式輸入的每一個命令都是一個代碼塊。兩個機制:若是在同一代碼塊下,則採用同一代碼塊下的換緩存機制。若是是不一樣代碼塊,則採用小數據池的駐留機制緩存

    • 同一個代碼塊的緩存機制(字符串駐留機制):機制內容:Python在執行同一個代碼塊的初始化對象的命令時,會檢查是否其值是否已經存在,若是存在,會將其重用。換句話說:執行同一個代碼塊時,遇到初始化對象的命令時,他會將初始化的這個變量與值存儲在一個字典中,在遇到新的變量時,會先在字典中查詢記錄,若是有一樣的記錄那麼它會重複使用這個字典中的以前的這個值,即:id相同。app

      適用對象int(float)::任何數字在同一代碼塊下都會複用。函數

      str:幾乎全部的字符串都會符合緩存機制(1,非乘法獲得的字符串都知足代碼塊的緩存機制,,乘法獲得的字符串分兩種狀況:1. 乘數爲1時,任何字符串知足代碼塊的緩存機制,2. 乘數>=2時,僅含大小寫字母,數字,下劃線,總長度<=20,知足代碼塊的緩存機制)性能

      s1 = 'iam'*1
      s2 = 'iam'*1
      print(s1 is s2)
      >>>True

      bool:True和False在字典中會以1,0方式存在,而且複用。測試

      優勢:可以提升一些字符串,整數處理人物在時間和空間上的性能;須要值相同的字符串,整數的時候,直接從‘字典’中取出複用,避免頻繁的建立和銷燬,提高效率,節約內存。優化

    • 在不一樣一個代碼塊內的緩存機制:小數據池,也稱爲小整數緩存機制,或者稱爲駐留機制等等。Python自動將-5~256的整數進行了緩存,當你將這些整數賦值給變量時,並不會從新建立對象,而是使用已經建立好的緩存對象。code

      python會將必定規則的字符串在字符串駐留池中,建立一份,當你將這些字符串賦值給變量時,並不會從新建立對象, 而是使用在字符串駐留池中建立好的對象。htm

        其實,不管是緩存仍是字符串駐留池,都是python作的一個優化,就是將~5-256的整數,和必定規則的字符串,放在一個‘池’(容器,或者字典)中,不管程序中那些變量指向這些範圍內的整數或者字符串,那麼他直接在這個‘池’中引用,言外之意,就是內存中之建立一個。

      適用對象int(float):那麼你們都知道對於整數來講,小數據池的範圍是-5~256 ,若是多個變量都是指向同一個(在這個範圍內的)數字,他們在內存中指向的都是一個內存地址。

      # pycharm 經過運行文件的方式執行下列代碼:  這是在同一個文件下也就是同一代碼塊下,採用同一代碼塊下的緩存機制。
      i1 = 1000
      i2 = 1000
      print(i1 is i2)  # 結果爲True 由於代碼塊下的緩存機制適用於全部數字
      >>>True
      
      
      #經過交互方式中執行下面代碼,這是不一樣代碼塊下,則採用小數據池的駐留機制。
      >>> i1 = 1000
      >>> i2 = 1000
      >>> print(i1 is i2)
      False  # 不一樣代碼塊下的小數據池駐留機制 數字的範圍只是-5~256.

      str:1.字符串的長度爲0或者1,默認都採用了駐留機制(小數據池)。2.字符串的長度>1,且只含有大小寫字母,數字,下劃線時,纔會默認駐留。3.用乘法獲得的字符串,分兩種狀況:1 乘數爲1,知足規則的字符串,默認駐留。2. 乘數>=2時:僅含大小寫字母,數字,下劃線,總長度<=20,默認駐留。

      #4.指定駐留
      from sys import intern
      a = intern('hello!@'*20)
      b = intern('hello!@'*20)
      print(a is b)
      >>>True
      #指定駐留是你能夠指定任意的字符串加入到小數據池中,讓其只在內存中建立一個對象,多個變量都是指向這一個字

      bool值就是True,False,不管你建立多少個變量指向True,False,那麼他在內存中只存在一個。

      # 雖然在同一個文件中,可是函數自己就是代碼塊,因此這是在兩個不一樣的代碼塊下,不知足小數據池(駐存機制),則指向兩個不一樣的地址。
      def func():
          i1 = 1000
          print(id(i1))  # 2288555806672
      
      def func2():
          i1 = 1000
          print(id(i1))  # 2288557317392
      
      func()
      func2()

      優勢:可以提升一些字符串,整數處理人物在時間和空間上的性能;須要值相同的字符串,整數的時候,直接從‘池’裏拿來用,避免頻繁的建立和銷燬,提高效率,節約內存

參考文章:https://www.cnblogs.com/jin-xin/articles/9439483.html

  • 集合 (set):容器型數據類型,要求它裏面的元素是不可變的數據(可哈希),但它自己是可變的數據類型(不可哈希)。集合是無序的。以{}存放數據。

    • 做用:列表的去重;關係的測試(交集,並集…)

      /1. 集合的建立:

      set = {1,2,'a'}
      #空集合的表示:
      set1 = set()   #set1 = {}表示空字典

      /2 . 增:add update()#迭代增長,有重複的則去重

      set1 = {1,2}
      set1.add('a')
      print(set1)
      >>>{'a', 1, 2}  #集合無序
      
      set1.update('asdfdsa')
      print(set1)
      >>>{'a', 1, 2, 'f', 's', 'd'}

      /3. 刪:remove()(按照元素刪除,pop()隨機刪除,clear()清空集合 del 刪除集合

      set1 = {'a', 1, 2, 'f', 's', 'd'}
      set1.remove('a')
      print(set1)
      >>>{1, 2, 's', 'f', 'd'}
      
      set1.pop()
      print(set1)
      >>>{2, 's', 'f', 'd'}
      
      set1.clear()
      print(set1)
      >>>{}
      
      del set1

      /4. 改:先刪除再增長

    • 交、並、

      /1 . 交集。(&或者intersection) 集合共同有的元素

      set1 = {1,2,3}
      set2 = {2,3,4}
      print(set1 & set2) #or print(set1.intersection)
      >>>{2,3}

      /2. 並集。(|或者union)集合全部的元素

      set1 = {1,2}
      set2 = {2,3}
      print(set1 | set2) #or print(set1.union(set2))
      >>>{1,2,3}

      /3. 差集 ( - 或者difference) ,前一集合獨有的元素

      set1 = {1,2,3,4,5}
      set2 = {2,4,6}
      print(set1 - set2) #or print(set1.difference(set2))
      >>>{1,3,5}

      /4 . 反交集。(^ 或者symmetric_difference)每一個集合獨有的元素

      set1 = {1,2,3,4,5}
      set2 = {3,4,5,6,7}
      print(set1 ^ set2) #or print(set1.symmetric_difference(set2))
      >>>{1,2,6,7}

      /5. 子集與超集

      set1 = {1,2}
      set2 = {1,2,3}
      print(set1 < set2)
      >>>True
      print(set1.issubset(set2))    #set1是set2的子集
      >>>True
      
      print(set2 > set1)
      >>>True
      print(set2.issuperset(set1)) #set2是set1的超集
      >>>True

      /6. frozenset()讓集合變爲不可變類型

      s = frozenset('qweasd')
      print(s,type(s))
      >>>frozenset({'q', 'e', 'w', 's', 'a', 'd'}) <class 'frozenset'>
  • 深淺copy

    • 淺copy:在內存中開闢一個新的空間存放copy的對象(列表、字典),可是裏面的全部元素與被copy對象的裏面的元素共用一個。

      l1 = [1,2]    
      l2 = l1
      l1.append(3)
      print(l2)
      >>>[1,2,3] #l1,l2兩變量指向同一個id(數據)
      
      
      #淺copy
      l3 = [1,2,['a']]
      l4 = l3.copy()
      l3.append(3)   
      print(l3)
      >>>[1,2,['a'],3]
      print(l4)
      >>>[1,2,['a']]
      
      
      l3[-2].append(4)    #or l4[-1].append(4)
      print(l3)
      >>>[1, 2, ['a', 4], 3]
      print(l4)  
      >>>[1,2,['a',4]] #l4與l3列表中的數據id是相同的,但l4與l3列表id不相同,即l3中的每一個元素與l4中的每一個元素使用的是相同的一個id,但l4與l3用的不是同一個id。

      其實列表第一個一個的槽位,它儲存的是對象的內存地址。淺拷貝仍然使用原來的對象的內存地址。對儲存的可變對象能夠進行更改;若改變不可變類型,則改變的不是不可變類型自己,而是變量的指向關係

  • 深copy,需導入模塊copy(淺copy也能夠導入copy模塊),不可變的數據類型沿用以前的內存地址,可變的數據類型建立新的內存地址。

    import copy
    l3 = [1,2,['a']]
    l4 = copy.deepcopy(l3)      #淺copy爲  l4 = copy.copy(l3)
    l3[-1].append(3)
    print(l3)
    >>>[1,2,['a',3]]
    print(l4)
    >>>[1,2,['a']]              #淺copy輸出爲  [1,2,['a',3]]
    #列表第一個一個的槽位,它儲存的是對象的內存地址。深拷貝會建立一個新的對象的內存地址。

    python對深copy作了一個優化,將對象爲不可變數據類型的內存地址沿用同一個,只從新再建立一份可變數據類型的內存地址。

    淺copy:(list,dict),嵌套的可變的數據類型是同一個。

    深copy:(list,dict),嵌套的可變的數據類型不是同一個。

l1 = [1,2,['a']]
l2 = l1[:]
l1[-1].append(3)
print(l2)
>>>[1,2,['a',3]]  #切片是淺copy

補充內置函數:

l1 = ['a','b','c']
for i in enumerate(l1,start=50):  #start可默認不寫
    print(i)
>>>(50, 'a')
(51, 'b')
(52, 'c')

#小題試作,看代碼寫結果:
#1:
l1 = [1,2,3,[4,5]]
l2 = [1,2,3,[4,5]]

a = l1 == l2     #先看等號右邊
b = l1 is l2
print(a)     #True
print(b)     #False

#2.
data_list = []
for i in range(10):
    data = {}
    data['age'] = i   
    data_list.append(data)
print(data)
>>>{'age': 9}
print(data_list)
>>>[{'age': 0}, {'age': 1}, {'age': 2}, {'age': 3}, {'age': 4}, {'age': 5}, {'age': 6}, {'age': 7}, {'age': 8}, {'age': 9}]



#對比:
data_list = []
data = {}
for i in range(10):
    data['age'] = i   
    data_list.append(data)
print(data_list)
>>>[{'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}, {'age': 9}]
相關文章
相關標籤/搜索