日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

流畅的Python 2. 数据结构 - 序列构成的数组

發布時間:2024/7/5 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 流畅的Python 2. 数据结构 - 序列构成的数组 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1. 內置序列
    • 2. 列表推導 []、生成器() 表達式
    • 3. 元組 tuple
    • 4. 切片
    • 5. `+, *` 操作
    • 6. 增量賦值
    • 7. 排序
    • 8. bisect管理已排序序列
      • 8.1 用 bisect.bisect 二分搜索
      • 8.2 用 bisect.insort 二分插入新元素
    • 9. 列表的替代
      • 9.1 數組
      • 9.2 內存視圖
      • 9.3 NumPy、SciPy
      • 9.4 隊列

1. 內置序列

  • 容器序列:list, tuple, collections.deque 能存放不同類型的數據,存放的是對象的引用
  • 扁平序列:str, bytes, bytearray, memoryview, array.array 只能存一種類型,存放的是(只能存字符、字節、數值這種基礎類型)

按照是否可修改:

  • 可變序列:list,bytearray,array.array,collections.deque,memoryview
  • 不可變序列:tuple, str, bytes

2. 列表推導 []、生成器() 表達式

  • 列表推導有自己的局部作用域
# 列表推導有自己的局部作用域 x = "ABC" y = [ord(x) for x in x] print(x) # ABC, x 沒有被覆蓋 print(y) # [65, 66, 67]
  • 列表推導式,只能生成列表類型
# 列推導更簡單 symbols = '$¢£¥€¤' beyond_ascii = [ord(s) for s in symbols if ord(s) > 127] print(beyond_ascii) # [162, 163, 165, 8364, 164] beyond_ascii = list(filter(lambda c: c > 127, map(ord, symbols))) print(beyond_ascii) # [162, 163, 165, 8364, 164]# 注意以下兩個for的順序,先出現的變量,先遍歷完它的組合 colors = ['black', 'white'] sizes = ['S', 'M', 'L'] t_shirts = [(color, size) for color in colors for size in sizes] print(t_shirts) # [('black', 'S'), ('black', 'M'), ('black', 'L'), # ('white', 'S'), ('white', 'M'), ('white', 'L')]t_shirts = [(color, size) for size in sizes for color in colors] print(t_shirts) # [('black', 'S'), ('white', 'S'), # ('black', 'M'), ('white', 'M'), # ('black', 'L'), ('white', 'L')]

生成器表達式

  • 逐個的產出元素,背后遵守了迭代器協議,相比 列表 去初始化其他類型,生成器表達式 更節省內存,它不會一次性產生全部的組合
  • 語法跟列表推導差不多,把 [ ] 改成 ( )
# 生成器表達式 () symbols = '$¢£¥€¤' print(tuple(ord(symbol) for symbol in symbols)) import arrayprint(array.array('I', (ord(symbol) for symbol in symbols))) # ord(symbol) 外面需要括號,因為array需要2個構造參數 # typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)for t_shirt in ('{}, {}'.format(c, s) for c in colors for s in sizes):print(t_shirt) # black, S # black, M # black, L # white, S # white, M # white, L

3. 元組 tuple

  • 不可變的列表
  • 還可用于 沒有字段名的記錄
lax_coordinates = (33.9425, -118.408056) city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014) traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'), ('ESP', 'XDA205856')] for passport in sorted(traveler_ids):print('{}/{}'.format(passport[0], passport[1]))print('%s/%s' % passport) # 跟上面的等價, % 運算符把對應元素對應到 %s 處
  • 元組拆包 %, = 必須保證兩側的元素數量一樣,不一樣多,可以使用 * 忽略多余元素
lax_coordinates = (33.9425, -118.408056) latitude, longitude = lax_coordinates # 元組拆包 print(latitude, longitude) # 33.9425 -118.408056a, b = 1, 2 a, b = b, a print(a, b) # 2 1print(divmod(20, 8)) # (2, 4) t = (20, 8) print(divmod(*t)) # *運算符把可迭代對象拆開作為函數的參數 # (2, 4) quotient, remainder = divmod(*t) print(quotient, remainder) # 2 4import os path, filename = os.path.split("c:/abd/tuple.py") print(path) # c:/abd print(filename) # tuple.py
  • * 代替多個元素
a, b, *rest = range(5) print(a, b, rest) # 0 1 [2, 3, 4] a, b, *rest = range(3) print(a, b, rest) # 0 1 [2] a, b, *rest = range(2) # 不能少于兩個元素 print(a, b, rest) # 0 1 []a, *body, c, d = range(5) print(a, body, c, d) # 0 [1, 2] 3 4 *head, b, c, d = range(5) print(head, b, c, d) # [0, 1] 2 3 4
  • 嵌套元組拆包
metro_areas = [('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)), ]print('{:>15} | {:<9} | {:^9}'.format('table', 'lat.', 'long.')) # < 左對齊(默認),^居中對齊 > 右對齊 fmt = '{:15} | {:9.3f} | {:9.4f}' # w寬度.n小數點位數 for name, cc, pop, (latitude, longitude) in metro_areas:if longitude <= 0:print(fmt.format(name, latitude, longitude)) # table | lat. | long. # Mexico City | 19.433 | -99.1333 # New York-Newark | 40.809 | -74.0204 # Sao Paulo | -23.548 | -46.6358
  • 有名字的元組 collections.namedtuple ,構建一個帶字段名的元組和一個有名字的類
  • 其構建的實例比普通對象小一些,因為它不會用 __dict__ 來存放屬性
from collections import namedtupleCity = namedtuple('City', 'name country population coordinates') # 類名, 各個字段名字(數個字符串的可迭代對象 or 空格分割的字符串) tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) # 只接受單一可迭代對象 print(tokyo) print(tokyo.population) # 通過字段名獲取屬性 print(tokyo.coordinates) print(tokyo[1]) # 通過位置獲取屬性print(City._fields) # 類的所有字段名 ('name', 'country', 'population', 'coordinates') LatLong = namedtuple('LatLong', 'lat long') delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889)) delhi = City._make(delhi_data) # 生成類的實例 跟 City(*delhi_data) 一樣 print(delhi._asdict()) # 以collections.OrderedDict的形式返回 for k, v in delhi._asdict().items():print(k + ':', v)

4. 切片

像 list, tuple, str 等序列類型都支持切片

  • seq[start:stop:step] 從 start 開始,到 stop(不包含)結束,每間隔 step 個取一次,其調用seq.__getitem__(slice(start, stop, step))
# slice invoice = """ 1909 Pimoroni PiBrella $17.50 3 $52.50 1489 6mm Tactile Switch x20 $4.95 2 $9.90 1510 Panavise Jr. - PV-201 $28.00 1 $28.00 1601 PiTFT Mini Kit 320x240 $34.95 1 $34.95 """ SKU = slice(0, 6) DESCRIPTION = slice(6, 30) UNIT_PRICE = slice(30, 37) QUANTITY = slice(37, 39) ITEM_TOTAL = slice(39, None) line_items = invoice.split('\n')[1:] for item in line_items:print(item[UNIT_PRICE], item[DESCRIPTION]) # $17.50 Pimoroni PiBrella # $4.95 6mm Tactile Switch x20 # $28.00 Panavise Jr. - PV-201 # $34.95 PiTFT Mini Kit 320x240
  • 給切片賦值(迭代對象),就地修改
# 給切片賦值, 就地修改 l = list(range(10)) print(l) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] l[2:5] = [20, 30] # 替換原list print(l) # [0, 1, 20, 30, 5, 6, 7, 8, 9] del l[5 : 7] # 刪除段 print(l) # [0, 1, 20, 30, 5, 8, 9] l[3::2] = [11, 22] print(l) # [0, 1, 20, 11, 5, 22, 9] # l[2:5] = 100 # Error can only assign an iterable

5. +, * 操作

  • 使用 + * ,拼接,產生新的序列
  • 注意 不要在 [[list]]*n 外側乘以 n ,它們 n 個都指向同一個list
# * + 操作 l = [1, "abc", 3] print(2 * l) # [1, 'abc', 3, 1, 'abc', 3] print(l) # [1, 'abc', 3] s = "abc" print(s * 2) # abcabc print(s) # abc# 注意,坑點 l = [[1, 2, 3]] * 3 print(l) # [[1, 2, 3], [1, 2, 3], [1, 2, 3]] l[0][0] = 100 # 內部都是指向一個列表 print(l) # [[100, 2, 3], [100, 2, 3], [100, 2, 3]]# 正確寫法 l = [[1, 2, 3] for i in range(3)] print(l) # [[1, 2, 3], [1, 2, 3], [1, 2, 3]] l[0][0] = 100 print(l) # [[100, 2, 3], [1, 2, 3], [1, 2, 3]]

6. 增量賦值

  • +=,*= 等,+= 背后對應于 __iadd__() 就地加法,如果類沒有實現這個方法,會調用 __add__()
# 增量操作 l = [1, 2, 3] print(id(l)) # 2408644481736 l *= 2 print(l) # [1, 2, 3, 1, 2, 3] print(id(l)) # 2408644481736 , 就地修改t = (1, 2, 3) print(id(t)) # 1930961968224 t *= 2 print(t) # (1, 2, 3, 1, 2, 3) print(id(t)) # 1930959535464 , 不可變對象,會產生新的對象(str例外)

7. 排序

  • list.sort() 就地排序,返回 None,沒有復制
  • 內置函數 sorted() ,會新建一個列表返回
  • 都有關鍵字,reverse 默認False升序, key排序函數(自定義,len,str.lower)

8. bisect管理已排序序列

8.1 用 bisect.bisect 二分搜索

def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):i = bisect.bisect(breakpoints, score)# bisect同bisect_right,相等的話返回后面的位置return grades[i]ans = [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] # bisect_left ['F', 'A', 'C', 'D', 'B', 'B', 'A'] # bisect_right ['F', 'A', 'C', 'C', 'B', 'A', 'A'] print(ans)

8.2 用 bisect.insort 二分插入新元素

insort(seq, item) 把變量 item 插入到序列 seq 中,并能保持 seq 的升序順序

import random, timerandom.seed(time.time()) l = [] for i in range(7):new_item = random.randrange(20)bisect.insort(l, new_item)print('{:2} ->'.format(new_item), l) # 17 -> [17] # 0 -> [0, 17] # 16 -> [0, 16, 17] # 6 -> [0, 6, 16, 17] # 13 -> [0, 6, 13, 16, 17] # 14 -> [0, 6, 13, 14, 16, 17] # 1 -> [0, 1, 6, 13, 14, 16, 17]

9. 列表的替代

9.1 數組

  • 只包含數字的列表,array.array 比 list 更高效,支持所有可變序列的操作
  • 還可以 從文件讀取 和 存入文件,.frombytes,.tofile
# 數組 from array import array from random import randomfloats = array('d', (random() for i in range(10 ** 7))) print(floats[-1]) # 0.7284759170264468 f = open("floats.bin", "wb") floats.tofile(f) f.close() floats1 = array('d') f = open("floats.bin", "rb") floats1.fromfile(f, 10 ** 7) f.close() print(floats[-1]) # 0.7284759170264468 print(floats == floats1) # True

pickle.dump 幾乎可以處理所有內置數字類型(復數,嵌套集合,自定義類)

9.2 內存視圖

  • 不復制,操作內容
# 內存視圖 nums = array('h', [-2, -1, 0, 1, 2]) # h 短整型有符號 menv = memoryview(nums) print(len(menv)) # 5 print(menv[0]) # -2 menv_oct = menv.cast('B') # B 無符號字符 print(menv_oct.tolist()) # [254, 255, 255, 255, 0, 0, 1, 0, 2, 0] menv_oct[5] = 4 # 操作位置上的字節 print(nums) # array('h', [-2, -1, 1024, 1, 2])

9.3 NumPy、SciPy

9.4 隊列

  • 列表在 頭部 pop,或者 insert 時,比較費時,會移動元素
  • collections.deque 類(雙向隊列)是一個線程安全、可以快速從兩端添加或者刪除元素的數據類型
# deque from collections import dequedq = deque(range(10), maxlen=10) print(dq) # deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10) dq.rotate(3) # 右移3個 print(dq) # deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10) dq.rotate(-4) # 左移4個 print(dq) # deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], maxlen=10) dq.appendleft(-1) print(dq) # deque([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10) dq.extend([11, 22, 33]) # 滿了,刪除另一端的 print(dq) # deque([3, 4, 5, 6, 7, 8, 9, 11, 22, 33], maxlen=10) dq.extendleft([10, 20, 30, 40]) # 逐個添加到左側 print(dq) # deque([40, 30, 20, 10, 3, 4, 5, 6, 7, 8], maxlen=10)
  • 還有一些 PriorityQueue,Queue,LifoQueue,heapq等隊列

總結

以上是生活随笔為你收集整理的流畅的Python 2. 数据结构 - 序列构成的数组的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。