python基礎之一——數據類型和內存管理

本博客所有文章僅僅是博主做筆記之用,博客內容並不詳細(以後有空會修改完善),思維也有跳躍之處,想詳細學習博客內容可參考文章後面的參考鏈接,祝學習快樂。

本節要點:

  1. 數據類型
  2. 內存管理
  3. 深淺copy

學習Python一定要記住的一點:一切皆對象!

數據類型

  • 整數

    和其他語言不同,Python所能表示的整數大小隻受限於機器內存,並無固定的字節數。

  • bool類型

    False和0表示假,其他的都爲真。

  • 浮點數

    注意兩點:

    1. 浮點數的精度依賴於解釋器,不同的IDE下可能不同
    2. 比較兩個浮點數不能用 a==b,而要用abs(a-b)<=sys.float_info.epsilon來判斷。
  • 字符串

    字符串常用方法:

 |  capitalize(...)
 |      S.capitalize() -> str
 |      
 |      Return a capitalized version of S, i.e. make the first character
 |      have upper case and the rest lower case.
 |  
 |  casefold(...)
 |      S.casefold() -> str
 |      
 |      Return a version of S suitable for caseless comparisons.
 |  
 |  center(...)
 |      S.center(width[, fillchar]) -> str
 |      
 |      Return S centered in a string of length width. Padding is
 |      done using the specified fill character (default is a space)
 |  
 |  count(...)
 |      S.count(sub[, start[, end]]) -> int
 |      
 |      Return the number of non-overlapping occurrences of substring sub in
 |      string S[start:end].  Optional arguments start and end are
 |      interpreted as in slice notation.
 |  
 |  encode(...)
 |      S.encode(encoding='utf-8', errors='strict') -> bytes
 |      
 |      Encode S using the codec registered for encoding. Default encoding
 |      is 'utf-8'. errors may be given to set a different error
 |      handling scheme. Default is 'strict' meaning that encoding errors raise
 |      a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and
 |      'xmlcharrefreplace' as well as any other name registered with
 |      codecs.register_error that can handle UnicodeEncodeErrors.
 |  
 |  endswith(...)
 |      S.endswith(suffix[, start[, end]]) -> bool
 |      
 |      Return True if S ends with the specified suffix, False otherwise.
 |      With optional start, test S beginning at that position.
 |      With optional end, stop comparing S at that position.
 |      suffix can also be a tuple of strings to try.
 |  
 |  expandtabs(...)
 |      S.expandtabs(tabsize=8) -> str
 |      
 |      Return a copy of S where all tab characters are expanded using spaces.
 |      If tabsize is not given, a tab size of 8 characters is assumed.
 |  
 |  find(...)
 |      S.find(sub[, start[, end]]) -> int
 |      
 |      Return the lowest index in S where substring sub is found,
 |      such that sub is contained within S[start:end].  Optional
 |      arguments start and end are interpreted as in slice notation.
 |      
 |      Return -1 on failure.
 |  
 |  format(...)
 |      S.format(*args, **kwargs) -> str
 |      
 |      Return a formatted version of S, using substitutions from args and kwargs.
 |      The substitutions are identified by braces ('{' and '}').
 |  
 |  format_map(...)
 |      S.format_map(mapping) -> str
 |      
 |      Return a formatted version of S, using substitutions from mapping.
 |      The substitutions are identified by braces ('{' and '}').
 |  
 |  index(...)
 |      S.index(sub[, start[, end]]) -> int
 |      
 |      Like S.find() but raise ValueError when the substring is not found.
 |  
 |  isalnum(...)
 |      S.isalnum() -> bool
 |      
 |      Return True if all characters in S are alphanumeric
 |      and there is at least one character in S, False otherwise.
 |  
 |  isalpha(...)
 |      S.isalpha() -> bool
 |      
 |      Return True if all characters in S are alphabetic
 |      and there is at least one character in S, False otherwise.
 |  
 |  isdecimal(...)
 |      S.isdecimal() -> bool
 |      
 |      Return True if there are only decimal characters in S,
 |      False otherwise.
 |  
 |  isdigit(...)
 |      S.isdigit() -> bool
 |      
 |      Return True if all characters in S are digits
 |      and there is at least one character in S, False otherwise.
 |  
 |  isidentifier(...)
 |      S.isidentifier() -> bool
 |      
 |      Return True if S is a valid identifier according
 |      to the language definition.
 |      
 |      Use keyword.iskeyword() to test for reserved identifiers
 |      such as "def" and "class".
 |  
 |  islower(...)
 |      S.islower() -> bool
 |      
 |      Return True if all cased characters in S are lowercase and there is
 |      at least one cased character in S, False otherwise.
 |  
 |  isnumeric(...)
 |      S.isnumeric() -> bool
 |      
 |      Return True if there are only numeric characters in S,
 |      False otherwise.
 |  
 |  isprintable(...)
 |      S.isprintable() -> bool
 |      
 |      Return True if all characters in S are considered
 |      printable in repr() or S is empty, False otherwise.
 |  
 |  isspace(...)
 |      S.isspace() -> bool
 |      
 |      Return True if all characters in S are whitespace
 |      and there is at least one character in S, False otherwise.
 |  
 |  istitle(...)
 |      S.istitle() -> bool
 |      
 |      Return True if S is a titlecased string and there is at least one
 |      character in S, i.e. upper- and titlecase characters may only
 |      follow uncased characters and lowercase characters only cased ones.
 |      Return False otherwise.
 |  
 |  isupper(...)
 |      S.isupper() -> bool
 |      
 |      Return True if all cased characters in S are uppercase and there is
 |      at least one cased character in S, False otherwise.
 |  
 |  join(...)
 |      S.join(iterable) -> str
 |      
 |      Return a string which is the concatenation of the strings in the
 |      iterable.  The separator between elements is S.
 |  
 |  ljust(...)
 |      S.ljust(width[, fillchar]) -> str
 |      
 |      Return S left-justified in a Unicode string of length width. Padding is
 |      done using the specified fill character (default is a space).
 |  
 |  lower(...)
 |      S.lower() -> str
 |      
 |      Return a copy of the string S converted to lowercase.
 |  
 |  lstrip(...)
 |      S.lstrip([chars]) -> str
 |      
 |      Return a copy of the string S with leading whitespace removed.
 |      If chars is given and not None, remove characters in chars instead.
 |  
 |  partition(...)
 |      S.partition(sep) -> (head, sep, tail)
 |      
 |      Search for the separator sep in S, and return the part before it,
 |      the separator itself, and the part after it.  If the separator is not
 |      found, return S and two empty strings.
 |  
 |  replace(...)
 |      S.replace(old, new[, count]) -> str
 |      
 |      Return a copy of S with all occurrences of substring
 |      old replaced by new.  If the optional argument count is
 |      given, only the first count occurrences are replaced.
 |  
 |  rfind(...)
 |      S.rfind(sub[, start[, end]]) -> int
 |      
 |      Return the highest index in S where substring sub is found,
 |      such that sub is contained within S[start:end].  Optional
 |      arguments start and end are interpreted as in slice notation.
 |      
 |      Return -1 on failure.
 |  
 |  rindex(...)
 |      S.rindex(sub[, start[, end]]) -> int
 |      
 |      Like S.rfind() but raise ValueError when the substring is not found.
 |  
 |  rjust(...)
 |      S.rjust(width[, fillchar]) -> str
 |      
 |      Return S right-justified in a string of length width. Padding is
 |      done using the specified fill character (default is a space).
 |  
 |  rpartition(...)
 |      S.rpartition(sep) -> (head, sep, tail)
 |      
 |      Search for the separator sep in S, starting at the end of S, and return
 |      the part before it, the separator itself, and the part after it.  If the
 |      separator is not found, return two empty strings and S.
 |  
 |  rsplit(...)
 |      S.rsplit(sep=None, maxsplit=-1) -> list of strings
 |      
 |      Return a list of the words in S, using sep as the
 |      delimiter string, starting at the end of the string and
 |      working to the front.  If maxsplit is given, at most maxsplit
 |      splits are done. If sep is not specified, any whitespace string
 |      is a separator.
 |  
 |  rstrip(...)
 |      S.rstrip([chars]) -> str
 |      
 |      Return a copy of the string S with trailing whitespace removed.
 |      If chars is given and not None, remove characters in chars instead.
 |  
 |  split(...)
 |      S.split(sep=None, maxsplit=-1) -> list of strings
 |      
 |      Return a list of the words in S, using sep as the
 |      delimiter string.  If maxsplit is given, at most maxsplit
 |      splits are done. If sep is not specified or is None, any
 |      whitespace string is a separator and empty strings are
 |      removed from the result.
 |  
 |  splitlines(...)
 |      S.splitlines([keepends]) -> list of strings
 |      
 |      Return a list of the lines in S, breaking at line boundaries.
 |      Line breaks are not included in the resulting list unless keepends
 |      is given and true.
 |  
 |  startswith(...)
 |      S.startswith(prefix[, start[, end]]) -> bool
 |      
 |      Return True if S starts with the specified prefix, False otherwise.
 |      With optional start, test S beginning at that position.
 |      With optional end, stop comparing S at that position.
 |      prefix can also be a tuple of strings to try.
 |  
 |  strip(...)
 |      S.strip([chars]) -> str
 |      
 |      Return a copy of the string S with leading and trailing
 |      whitespace removed.
 |      If chars is given and not None, remove characters in chars instead.
 |  
 |  swapcase(...)
 |      S.swapcase() -> str
 |      
 |      Return a copy of S with uppercase characters converted to lowercase
 |      and vice versa.
 |  
 |  title(...)
 |      S.title() -> str
 |      
 |      Return a titlecased version of S, i.e. words start with title case
 |      characters, all remaining cased characters have lower case.
 |  
 |  translate(...)
 |      S.translate(table) -> str
 |      
 |      Return a copy of the string S in which each character has been mapped
 |      through the given translation table. The table must implement
 |      lookup/indexing via __getitem__, for instance a dictionary or list,
 |      mapping Unicode ordinals to Unicode ordinals, strings, or None. If
 |      this operation raises LookupError, the character is left untouched.
 |      Characters mapped to None are deleted.
 |  
 |  upper(...)
 |      S.upper() -> str
 |      
 |      Return a copy of S converted to uppercase.
 |  
 |  zfill(...)
 |      S.zfill(width) -> str
 |      
 |      Pad a numeric string S with zeros on the left, to fill a field
 |      of the specified width. The string S is never truncated.

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

字符串格式規約
這裏寫圖片描述
語法格式:
[fill][align][sign][#][0][width][.][.precision][type]

參數解析:
fill: any character except ‘}’, 填充字符
align: ”<“left,“ >”right, “^”center 對齊方式, “=”用於在符號與數字之間進行填充(.format(int))
sign: “+” | “-” | ” ” 數字是否帶正負標識,“+”表示必須輸出符號,“-”表示只輸出負數符號,“ ”空格表示爲正數輸出空格,爲負數輸出“-”
#: 整數前綴爲 0b, 0o, 0x
width: 最小寬度
precision: 浮點型小數位數或字符串的最大長度
type: “b” | “c” | “d” | “e” | “E” | “f” | “g” | “G” | “n” | “o” | “x” | “X” | “%” 類型

字符串格式規約是使用冒號(:)引入的,其後跟隨可選的字符——一個填充字符(也可沒有)與一個對齊字符(<用於左對齊,>用於右對齊,^用於中間對齊),之後跟隨的是可選的最小寬度(整數),若需要指定最大寬度,就在其後使用句點,句點後跟隨一個整數。
注意:如果我們指定了一個填充字符,就必須同時指定對齊字符。

>>> s="Simple is better than complex."
>>> "{}".format(s)             #一般格式
'Simple is better than complex.'
>>> "{:40}".format(s)   #最小40個字符
'Simple is better than complex.          '
>>> "{:>40}".format(s)
'          Simple is better than complex.'
>>> "{:^40}".format(s)
'     Simple is better than complex.     '
>>> "{:-^40}".format(s)
'-----Simple is better than complex.-----'
>>> "{:.<40}".format(s)  #指定了一個填充字符,就必須同時指定對齊字符。
'Simple is better than complex...........'
>>> "{:.10}".format(s)  #最長10個字符
'Simple is '
>>> "{:#=40}".format("-34546")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: '=' alignment not allowed in string format specifier
>>> "{:#=40}".format(34546)
'###################################34546'

>>> "{: }".format(12345)
' 12345'
>>> "{:*^ 15}".format(1234)
'***** 1234*****'
>>> "{:*^-15}".format(1234)
'*****1234******'
>>> "{:*^-15}".format(-1234)
'*****-1234*****'
>>> "{:*^+15}".format(1234)
'*****+1234*****'
>>> "{:*^#15x}".format(1234)
'*****0x4d2*****'
>>> "{:*^#15b}".format(34)
'***0b100010****'

  • 列表
 |  append(...)
 |      L.append(object) -> None -- append object to end
 |  
 |  clear(...)
 |      L.clear() -> None -- remove all items from L
 |  
 |  copy(...)
 |      L.copy() -> list -- a shallow copy of L
 |  
 |  count(...)
 |      L.count(value) -> integer -- return number of occurrences of value
 |  
 |  extend(...)
 |      L.extend(iterable) -> None -- extend list by appending elements from the iterable
 |  
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value.
 |      Raises ValueError if the value is not present.
 |  
 |  insert(...)
 |      L.insert(index, object) -- insert object before index
 |  
 |  pop(...)
 |      L.pop([index]) -> item -- remove and return item at index (default last).
 |      Raises IndexError if list is empty or index is out of range.
 |  
 |  remove(...)
 |      L.remove(value) -> None -- remove first occurrence of value.
 |      Raises ValueError if the value is not present.
 |  
 |  reverse(...)
 |      L.reverse() -- reverse *IN PLACE*
 |  
 |  sort(...)
 |      L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
  • 元組
 |  count(...)
 |      T.count(value) -> integer -- return number of occurrences of value
 |  
 |  index(...)
 |      T.index(value, [start, [stop]]) -> integer -- return first index of value.
 |      Raises ValueError if the value is not present.
  • 字典
 |  clear(...)
 |      D.clear() -> None.  Remove all items from D.
 |  
 |  copy(...)
 |      D.copy() -> a shallow copy of D
 |  
 |  fromkeys(iterable, value=None, /) from builtins.type
 |      Returns a new dict with keys from iterable and values equal to value.
 |  
 |  get(...)
 |      D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
 |  
 |  items(...)
 |      D.items() -> a set-like object providing a view on D's items
 |  
 |  keys(...)
 |      D.keys() -> a set-like object providing a view on D's keys
 |  
 |  pop(...)
 |      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
 |      If key is not found, d is returned if given, otherwise KeyError is raised
 |  
 |  popitem(...)
 |      D.popitem() -> (k, v), remove and return some (key, value) pair as a
 |      2-tuple; but raise KeyError if D is empty.
 |  
 |  setdefault(...)
 |      D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
 |  
 |  update(...)
 |      D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
 |      If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]
 |      If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v
 |      In either case, this is followed by: for k in F:  D[k] = F[k]
 |  
 |  values(...)
 |      D.values() -> an object providing a view on D's values
  • bytes和bytearray類型(Python 3新增類型)

  • set和frozenset
    只有可哈希運算的對象纔可以添加到集合中。所有內置的固定數據類型(int,str,tuple,float,frozeset)都是可哈希運算的,可以添加到集合中,內置的可變數據類型(list,dict,set)都是不可哈希運算的,因爲其哈希值會隨着數據項的變化而變化,所以不能添加到集合中。

內存管理

再次重複開頭的一句話:一切皆對象

1. Python變量、對象、引用、存儲

python語言是一種解釋性的編程語言,在運行的過程中,逐句將指令解釋成機器碼,所以造就了python語言一些特別的地方。

Python有個特別的機制,它會在解釋器啓動的時候事先分配好一些緩衝區,這些緩衝區部分是固定好取值,例如整數[-5,256]的內存地址是固定的(這裏的固定指這一次程序啓動之後,這些數字在這個程序中的內存地址就不變了,但是啓動新的python程序,兩次的內存地址不一樣)。
另外,Python在啓動的時候還會有一塊可重複利用的緩衝區。

#固定緩衝區
>>> a=-5
>>> b=-5
>>> id(-5)
505370256
>>> id(a)
505370256
>>> id(b)
505370256
>>> c=256
>>> d=256
>>> print(id(c),id(d),id(256))
505374432 505374432 505374432
>>> e=257
>>> f=257
>>> print(id(e),id(f),id(257))
54155072 54155104 54155120

#可重複利用緩衝區(不同電腦,不同編譯器,有可能不一樣)
>>> id(10000)
2660846579440
>>> id(1000010)
2660846579440
>>> id(1000)
2660846579440
>>> id(1233)
2660846579440

對於列表和元組,存儲的其實並不是數據項,而是每個元素的引用。

這裏寫圖片描述

如圖,對於列表,L是這個列表對象的引用,對象裏面存的是每個元素的引用,而不是直接存儲數據。

當把一個list變量賦值給另外一個變量時,這兩個變量是等價的,它們都是原來對象的一個引用。

>>> a=[1,2,3,[1,2]]
>>> b=a
>>> print(id(a),id(b))
56164304 56164304
>>> b[1]="hello"
>>> a
[1, 'hello', 3, [1, 2]]
>>> b
[1, 'hello', 3, [1, 2]]
>>> b[3].append(9)
>>> a
[1, 'hello', 3, [1, 2, 9]]
>>> b
[1, 'hello', 3, [1, 2, 9]]

但是實際使用中,可能需要的是將裏面的內容給複製出來到一個新的地址空間,這裏可以使用python的copy模塊,copy模塊分爲兩種拷貝,一種是淺拷貝,一種是深拷貝。

二者唯一的區別在於對複合類型對象的處理上,比如列表和類實例。

假設處理一個list對象,淺拷貝調用函數copy.copy(),產生了一塊新的內存來存放list中的每個元素引用,也就是說每個元素的跟原來list中元素地址是一樣的。而深複製copy.deepcopy(),會開闢一塊新的內存來存放複合類型。

>>> a=[1234,"123",[1,2,899]]
>>> b=copy.copy(a)
>>> c=copy.deepcopy(a)
>>> print(id(a),id(b),id(c))
52773272 52624680 52625320  #這是三個不同的對象
>>> print(id(a[0]),id(b[0]),id(c[0]))
52320176 52320176 52320176   #對於簡單數據類型的處理是一樣的
>>> print(id(a[2]),id(b[2]),id(c[2]))
52774512 52774512 52625160  # 注意啦,區別就在這

參考資料

  1. http://blog.csdn.net/sinat_20791575/article/details/52957758
  2. http://www.cnblogs.com/alex3714/articles/5465198.html
  3. http://chenrudan.github.io/blog/2016/04/23/pythonmemorycontrol.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章