【Python學習筆記】 第8章 列表與字典

来源:https://www.cnblogs.com/hiu-siu-dou/p/18409139
-Advertisement-
Play Games

目錄關鍵字unsigned和signed數據在電腦中的存儲原碼 與 補碼的轉化與硬體關係原,反,補的原理:整型存儲的本質變數存取的過程類型目前的作用十進位與二進位快速轉換大小端位元組序判斷當前機器的位元組序"負零"(-128)的理解截斷建議在無符號類型的數值後帶上u, 關鍵字unsigned和sign ...


列表

Python的列表是:

  • 任意對象的有序集合

  • 通過偏移訪問

  • 可變長度、異構以及任意嵌套

  • 屬於“可變序列”的分類

  • 對象引用數組

下表是常見/具有代表性的列表對象操作:

操作 解釋
L = [] 一個空的列表
L = [123, 'abc', 1.23, {}] 有四個項的列表,索引從0到3
L = list('spam') 一個可迭代對象元素的列表
L = list(range(-4, 4)) 連續整數的列表
L[i] 索引
L[i][j] 索引的索引(用於列表嵌套列表)
L[i:j] 分片
len(L) 求長度
L1 + L2 拼接
L * 3 重覆
for x in L: print(x) 迭代
3 in L 成員關係
L.append(4) 尾部添加
L.extend([5, 6, 7]) 尾部擴展
L.insert(i, X) 插入
L.index(X) 索引
L.count(X) 統計元素出現個數
L.sort() 排序
L.reverse() 反轉
L.copy() 複製
L.clear() 清除
L.pop(i) 刪除i處元素,並將其返回
L.remove(X) 刪除元素X
del L[i] 刪除i處元素
del L[i:j] 刪除ij處的片段
L[i:j] = [] 刪除ij處的片段
L[i] = 3 索引賦值
L[i:j] = [4, 5, 6] 分片賦值
L = [x ** 2 for x in range(5)] 列表推導和映射
list(map(ord, 'spam')) 構造列表

列表的字面量表達式是一系列對象,括在方括弧里並用逗號隔開。上面的表中的一些操作與字元串類似。

列表的實際應用

基本列表操作:

len求長度、+拼接、*重覆:

>>> len([1, 2, 3])
3
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> ['Ni!'] * 4
['Ni!', 'Ni!', 'Ni!', 'Ni!']

這裡要求+的兩邊必須是列表,否則會出現類型錯誤。

列表迭代與推導

列表對所有序列操作都能做出相應,包括for

>>> 3 in [1, 2, 3]          # 3是否是列表的成員
True
>>> for x in [1, 2, 3]:     # 迭代
...     print(x, end=' ')
...
1 2 3

for會從左到右地遍歷任何序列中的項,對每一項執行每一條子句(在for語句後輸入提示符為...的若幹行)。

列表推導:通過對序列中的每一項應用一個表達式來構建新的列表的方式,用到for

>>> res = [c * 4 for c in 'SPAM']
>>> res
['SSSS', 'PPPP', 'AAAA', 'MMMM']

相較於使用for語句構造列表,列表推導更簡單。map也能實現類似效果,它對序列中的每一項應用一個函數,並把結果收集到一個新的列表中:

>>> list(map(abs, [-1, -2, 0, 1, 2]))
[1, 2, 0, 1, 2]

索引、分片和矩陣

索引和分片的操作與字元串相同。但是,列表索引的結果是指定偏移處的對象,而分片返回新列表:

>>> L = ['spam', 123, [1, 2, 3]]
>>> L[2]
[1, 2, 3]
>>> L[-2]
123
>>> a = L[2]
>>> L[2][1] = 4
>>> a
[1, 4, 3]

由於列表可以嵌套列表,我們有時候需要將幾次索引操作連在一起,以矩陣為例:

>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> matrix[1]
[4, 5, 6]
>>> matrix[1][1]
5

原位置修改列表

列表是可變的,支持原地修改。

索引與分片的賦值

可以將一個對象賦值給一個特定項(偏移)或整個片段(分片)來改變它的內容:

>>> L = ['spam', 'Spam', 'SPAM!']
>>> L[1] = 'eggs'
>>> L
['spam', 'eggs', 'SPAM!']
>>> L[0:2] = ['eat', 'more']
>>> L
['eat', 'more', 'SPAM!']

分片賦值可以分成兩步理解。插入:刪除等號左邊指定的分片;插入:將包含在等號右邊的可迭代對象中的片段插入舊分片被刪除的位置。這意味著,等號左邊分片的長度不一定要等於右邊列表的長度。

這樣,分片賦值可以寫成插入或刪除操作。

>>> L = [1, 2, 3]
>>> L[1:2] = [4, 5] # 替換
>>> L
[1, 4, 5, 3]
>>> L[1:1] = [6, 7] # 插入
>>> L
[1, 6, 7, 4, 5, 3]
>>> L[1:2] = []     # 刪除
>>> L
[1, 7, 4, 5, 3]

也可以用於在列表頭部拼接:

>>> L = [1]
>>> L[:0] = [2, 3, 4]
>>> L
[2, 3, 4, 1]
>>> L[len(L):] = [5, 6, 7]
>>> L

分片替換是強大的功能,但我們更經常用replaceinsert等。

列表方法調用

Python列表支持特定類型方法調用,這些方法可以原地修改列表。其中append方法在列表末尾添加單一對象(不生成新的列表),sort方法給列表中的內容排序。

>>> L = ['eat', 'more', 'SPAM!']
>>> L.append('please')
>>> L
['eat', 'more', 'SPAM!', 'please']
>>> L.sort()
>>> L
['SPAM!', 'eat', 'more', 'please']

更多關於列表排序

在預設情況下,sort使用Python的預設比較(這裡是字元串比較),以及升序排序。可以通過關鍵詞參數修改sort。關鍵詞參數是函數調用中的一種特殊的name=value語法,通過名字傳遞。

sort中,reverse指定排序是升序的,還是降序的;key參數返回在排序中使用的值,讓sort根據key(元素)的值給元素排序。

>>> L = ['abc', 'ABD', 'aBe']
>>> L.sort()
>>> L
['ABD', 'aBe', 'abc']
>>> L.sort(key=str.lower)
>>> L
['abc', 'ABD', 'aBe']
>>> L.sort(key=str.lower, reverse=True)
>>> L
['aBe', 'ABD', 'abc']

註意,appendsort修改原位置的列表對象,但不返回列表。如果我們要得到一個新的、重新排序的列表,並且要返回這個列表,那麼要用sorted(),他不會原地修改列表。

>>> L = ['abc', 'ABD', 'aBe']
>>> sorted(L, key=str.lower, reverse=True)
['aBe', 'ABD', 'abc']

其他常見的列表方法

reverse原地反轉列表,extend在末端插入多個元素,pop在末端刪除一個元素並返回這個元素。當然,也有reversed函數返回新的對象。

>>> L = [1, 2]
>>> L.extend([3, 4, 5])
>>> L
[1, 2, 3, 4, 5]
>>> L.pop()
5
>>> L
[1, 2, 3, 4]
>>> L.reverse()
>>> L
[4, 3, 2, 1]
>>> list(reversed(L))
[1, 2, 3, 4]

append也可以在尾部添加元素,但只能添加一個:

>>> L = []
>>> L.append(1)
>>> L.append(2)
>>> L
[1, 2]

pop可以接受偏移量,指定要刪除的元素。remove通過值刪除元素,insert在特定位置插入元素,count計算某元素的出現次數,index查找某元素第一次出現在列表中的位置。

>>> L = ['spam', 'eggs', 'ham']
>>> L.index('eggs')
1
>>> L.insert(1, 'toast')
>>> L
['spam', 'toast', 'eggs', 'ham']
>>> L.remove('eggs')
>>> L
['spam', 'toast', 'ham']
>>> L.pop(1)
'toast'
>>> L.count('spam')
1

其他常見列表操作

del可以刪除索引或分片:

>>> L = ['spam', 'eggs', 'ham', 'toast']
>>> del L[0]
>>> L
['eggs', 'ham', 'toast']
>>> del L[1:]
>>> L
['eggs']

這可以通過將一個分片L[i:j]賦值為空列表來實現。

L.copy()方法、L[:]list(L)都能實現列表的頂層複製。

字典

Python中的字典的主要屬性:

  • 通過鍵而不是偏移量來讀取

  • 任意對象的無序集合

  • 長度可變、異構、任意嵌套

  • 屬於“可變映射”類型(不支持序列操作)

  • 對象引用表(散列表)

常見/具有代表性的字典操作:

操作 解釋
D = {} 空字典
D = {'name': 'Bob', 'age': 40} 有兩個元素的字典
E = {'cto': {'name': 'Bob', 'age': 40}} 嵌套
D = dict(name='Bob', age=40) 通過關鍵字參數構造字典
D = dict([('name', 'Bob'), ('age', 40)]) 通過鍵值對構造字典
D = dict(zip(keylist, valslist)) 通過拉鏈式鍵值對構造字典
D = dict.fromkeys(['a', 'b']) 鍵列表
D['name'] 通過鍵索引
E['eto']['age'] 嵌套索引
'age' in D 成員關係:是否存在鍵
D.keys() 所有鍵
D.values() 所有值
D.items() 所有“鍵+值”元組
D.copy() 複製
D.clear() 刪除所有內容
D.update(D2) 通過鍵合併
D.get(key, default?) 通過鍵獲取,如果不存在預設返回None
D.pop(key, default?) 通過鍵刪除,如果不存在返回錯誤
D.setdefault(key, default?) 通過鍵獲取,如果不存在預設設置為None
D.popitem() 刪除/返回所有的鍵值
len(D) 長度(鍵值對的對數)
D[key] = 42 新增/修改鍵
del D [key] 根據鍵刪除條目
list(D.keys()) 查看字典鍵
D1.keys() & D2.keys()
Dictionary views 查看字典鍵
D = {x: x * 2 for x in range(10)} 字典推導

字典的實際應用

字典的基本操作

通常情況下,創建字典並通過鍵來存儲、訪問其中的某項:

>>> D = {'spam': 2, 'ham': 1, 'eggs': 3}
>>> D['spam']
2
>>> D
{'spam': 2, 'ham': 1, 'eggs': 3}

這裡的字典是D,鍵'spam'的值為2,我們用方括弧語法,用鍵對字典進行索引操作。

內置的len也適用於字典,返回存儲在字典中的元素的數目(鍵的數目);字典的in成員關係運算符檢查鍵是否在字典中;keys方法返回列表中所有的鍵。

>>> len(D)
3
>>> 'ham' in D
True
>>> list(D.keys())
['spam', 'ham', 'eggs']

註意,keys方法不返回列表,而是返回dict_keys類型,因此需要list轉換成列表。

原位置修改字典

字典也是可變的,因此可以在原位置對其修改、增大以及縮短。只需要給一個鍵賦值就可以改變或者生成元素。del也適用於字典,用於刪除作為索引的鍵相關聯的元素。字典支持所有類型,包括嵌套列表。

>>> D
{'spam': 2, 'ham': 1, 'eggs': 3}
>>> D['ham'] = ['grill', 'bake', 'fry'] # 改變索引對應的值
>>> D
{'spam': 2, 'ham': ['grill', 'bake', 'fry'], 'eggs': 3}
>>> del D['eggs']   # 刪除元素
>>> D
{'spam': 2, 'ham': ['grill', 'bake', 'fry']}
>>> D['brunch'] = 'Bacon'   # 生成元素(原來的字典沒有`'brunch'`鍵)
>>> D
{'spam': 2, 'ham': ['grill', 'bake', 'fry'], 'brunch': 'Bacon'}

其他字典方法

字典的valuesitems方法分別返回字典的所有值列表和(key, value)對元組。這兩個方法返回可迭代對象,可以將其轉換為列表。

>>> D = {'spam': 2, 'ham': 1, 'eggs': 3}
>>> list(D.values())
[2, 1, 3]
>>> list(D.items())
[('spam', 2), ('ham', 1), ('eggs', 3)]

讀取不存在的鍵會出錯,但是通過get方法讀取不存在的鍵會返回None或自定義的值。這對於不知道鍵是否存在的時候非常有用。

>>> D['spam']
2
>>> D.get('spam')
2
>>> D['toast']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'toast'
>>> D.get('toast')
>>> D.get('toast')
>>> print(D.get('toast'))
None
>>> print(D.get('toast', 0))
0

update方法類似於拼接,把一個字典的鍵和值拼接到另一個字典中。

>>> D
{'spam': 2, 'ham': 1, 'eggs': 3}
>>> D2 = {'spam': 3, 'toast': 4, 'muffin': 5}
>>> D.update(D2)
>>> D
{'spam': 3, 'ham': 1, 'eggs': 3, 'toast': 4, 'muffin': 5}

pop方法刪除一個鍵並返回值。

>>> D
{'spam': 3, 'ham': 1, 'eggs': 3, 'toast': 4, 'muffin': 5}
>>> D.pop('muffin')
5
>>> D.pop('toast')
4
>>> D
{'spam': 3, 'ham': 1, 'eggs': 3}

字典用法註意事項

  • 序列運算無效:字典的元素沒有“順序”的概念,因此拼接、分片無效;
  • 對新索引賦值會添加項
  • 鍵不一定總是字元串

用字典模擬靈活的列表:整數鍵

用較大的數作為偏移值修改列表中的值會報錯,但這種情況不會再字典中出現。

>>> L = []
>>> L[99] = 'spam'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>> D = {}
>>> D[99] = 'spam'
>>> D
{99: 'spam'}

用整數作為鍵,我們可以把字典看作更具有靈活性的表。

對稀疏數據結構使用字典:用元組作鍵

字典鍵也常用於實現稀疏數據結構。

>>> Matrix = {}
>>> Matrix[(2, 3, 4)] = 88
>>> Matrix[(7, 8, 9)] = 99
>>> X = 2
>>> Y = 3
>>> Z = 4
>>> Matrix[(X, Y, Z)]
88
>>> Matrix
{(2, 3, 4): 88, (7, 8, 9): 99}

這種方法可以只存儲兩個有值的點,而不是整個三維數組;缺點是不能訪問非存儲點的坐標。

避免鍵不存在錯誤

可以用iftry方法檢測值是否存在(這兩個方法在第10章學習)。


>>> if (2, 3, 6) in Matrix:
...     print(Matrix[(2, 3, 6)])
... else:
...     print(0)
...
0
>>> try:
...     print(Matrix[(2, 3, 6)])
... except KeyError:
...     print(0)
...
0

但是最簡潔的辦法是get

>>> Matrix.get((2, 3, 4), 0)
88
>>> Matrix.get((2, 3, 6), 0)
0

字典的嵌套

一般來說,字典可以取代搜索數據結構,並可以表示多種結構化信息。

Python的內置數據類型可以很輕鬆地表達結構化信息,下麵代碼可以一次性地寫好字典,而不是分開對每個鍵賦值:

>>> rec = {'name': 'Bob',
...        'jobs': ['developer', 'manager'],
...        'web': 'www.bobs.com/?Bob',
...        'home': {'state': 'Overworked', 'zip': 12345}}

訪問嵌套對象地元素時,只要簡單地把連續地索引操作用起來:

>>> rec['jobs'][1]
'manager'
>>> rec['home']['zip']
12345

創建字典地其他方式

創建字典有四種方式:

>>> # 第一種
>>> {'name': 'Bob', 'age': 40}
>>> # 第二種
>>> D = {}
>>> D['name'] = 'Bob'
>>> D['age'] = 40
>>> # 第三種
>>> dict(name='Bob', age=40)
>>> # 第四種
>>> dict([('name', 'Bob'), ('age', 40)])

適用條件:

  • 事先可以拼出整個字典:第一種;
  • 需要一次動態地建立字典地一個欄位:第二種;
  • 鍵是字元串:第三種;
  • 通過序列構建字典:第四種。

最後一種形式會與zip一起用,把程式運行時動態獲取的單獨鍵列表和單獨值列表一一對應拼接在一起:

dict(zip(keyslist, valueslist))

如果要所有鍵對應的值相同,我們可以用fromkeys方法初始化,傳入一個鍵的列表和一個初始值:

>>> dict.fromkeys(['a', 'b', 'c'], 0)
{'a': 0, 'b': 0, 'c': 0}

請留意:字典vs列表

列表將元素賦值給位置,而字典將元素賦值給更加便於記憶的鍵。在實際生活中,字典適用於存儲帶有標簽的數據,或者是通過名稱直接快速查詢的結構。

Python 3.X和2.7中的字典變化

Python 3.X中的列表:

  • 支持新的字典推導表達式
  • 對於D.keysD.valuesD.items方法,不是返回列表,而是其他可迭代對象
  • 不再直接支持相對大小的比較,而是手動比較
  • 沒有has_key,改為in成員關係測試

3.X和2.7的字典推導

我們可以用zip內置函數從值和鍵的列表中構造字典。

>>> D = dict(zip(['a', 'b', 'c'], [1, 2, 3]))
>>> D
{'a': 1, 'b': 2, 'c': 3}

在3.X和2.7中,我們可以用一個字典推導表達式來代替:

>>> D = {k: v for (k, v) in zip(['a', 'b', 'c'], [1, 2, 3])}
>>> D
{'a': 1, 'b': 2, 'c': 3}

我們可以使用推導把單獨的一串值映射到字典,可以用表達式計算:

>>> D = {x: x ** 2 for x in [1, 2, 3, 4]}
>>> D
{1: 1, 2: 4, 3: 9, 4: 16}
>>>
>>> D = {c: c * 4 for c in 'SPAM'}
>>> D
{'S': 'SSSS', 'P': 'PPPP', 'A': 'AAAA', 'M': 'MMMM'}

我們可以用這種字典推導,將所有鍵初始化到同一個值。

3.X中的字典視圖

在3.X中,字典的keysvaluesitems返回視圖對象,在2.X中返回列表。視圖對象是可迭代對象,但不是列表。

運行這三個方法的結果:

>>> D = dict(a=1, b=2, c=3)
>>> D
{'a': 1, 'b': 2, 'c': 3}
>>> D.keys()
dict_keys(['a', 'b', 'c'])
>>> list(D.keys())
['a', 'b', 'c']
>>> D.values()
dict_values([1, 2, 3])
>>> list(D.values())
[1, 2, 3]
>>> D.items()
dict_items([('a', 1), ('b', 2), ('c', 3)])
>>> list(D.items())
[('a', 1), ('b', 2), ('c', 3)]

Python 3.X的字典自己就有迭代器,它返回連續鍵。

>>> for key in D: print(key)
...
a
b
c

Python 3.X的字典視圖可以動態地反映視圖對象創建之後對字典做出的修改:

>>> K = D.keys()
>>> V = D.values()
>>> K, V
(dict_keys(['a', 'b', 'c']), dict_values([1, 2, 3]))
>>> del D['b']
>>> D
{'a': 1, 'c': 3}
>>> K
dict_keys(['a', 'c'])
>>> V
dict_values([1, 3])

字典視圖和集合

字典的keys可以視為集合,但values不能。

>>> K, V
(dict_keys(['a', 'c']), dict_values([1, 3]))
>>> K | {'x': 4}
{'c', 'x', 'a'}
>>> V & {'x': 4}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'dict_values' and 'dict'
>>> V & {'x': 4}.values()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'dict_values' and 'dict_values'

在集合操作中,視圖可能和其他視圖、集合和字典混合。

>>> D = {'a': 1, 'b': 2, 'c': 3}
>>> D.keys() & D.keys() # 視圖與視圖
{'b', 'c', 'a'}
>>> D.keys() & {'b'}    # 視圖與集合
{'b'}
>>> D.keys() & {'b': 1} # 視圖與字典
{'b'}

如果字典項視圖是可散列的,那麼它們可以被視為集合。

3.X中的字典鍵排序

我們不能直接對視圖對象進行排序,需要將其轉換為列表,或者對其進行sorted()函數,返回一個新的列表。

3.X中字典大小比較不再有效

在python 3.X中不能直接用<>比較字典相對大小,但可以用==

在 3.X中has_key方法已死:in方法萬歲

has_key方法已經在3.X取消,用in成員關係表達式代替。

>>> D
{'a': 1, 'b': 2, 'c': 3}
>>> D.has_key('c')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'has_key'
>>> 'c' in D
True

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

-Advertisement-
Play Games
更多相關文章
  • Spring 框架既可以從 廣義 和 狹義 兩個角度理解,下麵講解這兩個層面的概念: (本文主要講解的是狹義上的spring,廣義上的簡單概括) 1、spring 的含義 1. 廣義上的 Spring 從廣義上講,Spring 是一個涵蓋多個模塊的企業級應用開發框架,它提供了從基礎架構到複雜企業應用 ...
  • 題目描述 給你二叉樹的根節點 root 和一個表示目標和的整數 targetSum 。判斷該樹中是否存在 根節點到葉子節點 的路徑,這條路徑上所有節點值相加等於目標和 targetSum 。如果存在,返回 true ;否則,返回 false 。 葉子節點 是指沒有子節點的節點。 解題思路 我們這題採 ...
  • 在前後端分離模式下,Spring MVC 的作用主要集中在處理後端的業務邏輯和 API 介面,而不再直接管理視圖部分。也就是說,Spring MVC 的重點是如何處理客戶端的請求並返回數據(通常以 JSON 或 XML 格式),而視圖渲染交給前端框架(如 Vue.js、React 等)來完成。 下麵 ...
  • 目錄變數程式的本質:二進位文件1.變數:記憶體上的某個位置開闢的空間2.變數的初始化:3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地址1.1 關鍵字auto1.2 關鍵字register什麼樣的變數可以採用register? 變數 程式 ...
  • 題目描述 給定一個二叉樹的 根節點 root,請找出該二叉樹的 最底層 最左邊 節點的值。 假設二叉樹中至少有一個節點。 解題思路 這道題用層次遍歷的方式來說是比較簡單的,用遞歸的話如果我們看別人的精簡代碼很難看出其中隱藏的細節,這裡遞歸遍歷其實我們用到了回溯的思想,我們直接採用前序遍歷的方式(其實 ...
  • DataEase —— 開源的數據可視化分析工具,支持豐富的數據源連接,能夠通過拖拉拽方式快速製作圖表,並可以方便的與他人分享。 ...
  • 情況說明 在SpringBoot中集成了RocketMQ,實踐過程中,通過RocketMQ DashBoard觀察,生產者可以正常將進行消息提交;通過日誌及DashBoard觀察,消費者成功在RocketMQ中進行了註冊和訂閱且觀察到了消費者啟動的日誌行。問題是消費者依舊不會自動消費生產者提交的消息 ...
  • 題目描述 給定二叉樹的根節點 root ,返回所有左葉子之和。 解題思路 這裡我才用的是前序遍歷,我們在遍歷的時候因為是要手機左葉子節點,所以我們就不能等到遍歷當前節點的時候再去做判斷,應該遍歷到一個節點的時候就對其下一個節點的左右子樹進行判斷,這樣才能確保我們得到的是我們的左葉子節點 代碼實例 c ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...