Python線性數據結構

来源:https://www.cnblogs.com/singvis/archive/2020/03/27/12578929.html
-Advertisement-
Play Games

python線性數據結構 [TOC] 1 線性數據結構 本章要介紹的線性結構:list、tuple、string、bytes、bytearray。 線性表:是一種抽象的數學概念,是一組元素的序列的抽象,由有窮個元素組成(0個或任意個)。 線性表又可分為 順序表和鏈接表。 順序表:一組元素在記憶體中有序 ...


python線性數據結構

目錄


<center>碼好python的每一篇文章.</center>

1 線性數據結構

本章要介紹的線性結構:list、tuple、string、bytes、bytearray。

  • 線性表:是一種抽象的數學概念,是一組元素的序列的抽象,由有窮個元素組成(0個或任意個)。

    線性表又可分為 順序表和鏈接表。

  • 順序表:一組元素在記憶體中有序的存儲。列表list就是典型的順序表。

  • 鏈接表:一組元素在記憶體中分散存儲鏈接起來,彼此知道連接的是誰。

    對於這兩種表,數組中的元素進行查找、增加、刪除、修改,看看有什麼影響:

  • 查找元素

    對於順序表,是有序的在記憶體中存儲數據,可快速通過索引編號獲取元素,效率高。。

    對於鏈接表是分散存儲的,只能通過一個個去迭代獲取元素,效率差。

  • 增加元素

    對於順序表,如果是在末尾增加元素,對於整個數據表來說沒什麼影響,但是在開頭或是中間插入元素,後面的所有元素都要重新排序,影響很大(想想數百萬或更大數據量)。

    對於鏈接表,不管在哪裡加入元素,不會影響其他元素,影響小。

  • 刪除元素
    對於順序表,刪除元素和增加元素有著一樣的問題。
    對於鏈接表,不管在哪裡刪除元素,不會影響其他元素,影響小。

  • 修改元素
    對於順序表,可快速通過索引獲取元素然後進行修改,效率高。

    對於鏈接表,只能通過迭代獲取元素然後進行修改,效率低。

總結:順序表對於查找與修改效率最高,增加和刪除效率低。鏈接表則相反。

2.內建常用的數據類型

2.1 數值型

  • int 整數類型

    說明:整數包括負整數、0、正整數(... -2,-1,0,1,2, ...)。

    x1 = 1
    x2 = 0
    x3 = -1
    print(type(x1), x1)
    print(type(x2), x2)
    print(type(x3), x3)
    
    # 輸出結果如下:
    <class 'int'> 1
    <class 'int'> 0
    <class 'int'> -1
    

    int( )方法:可以將數字或字元串轉為整數,預設base=10,表示10進位,無參數傳入則返回0。

    x1 = int()
    x2 = int('1')
    x3 = int('0b10',base=2)  #base=2,表二進位,與傳入參數類型一致。
    x4 = int(3.14)
    print(type(x1), x1)
    print(type(x2), x2)
    print(type(x3), x3)
    print(type(x4), x4)
    
    # 輸出結果如下:
    <class 'int'> 0
    <class 'int'> 1
    <class 'int'> 2
    <class 'int'> 3
    
  • float 浮點類型
    說明:由整數和小數部分組成,傳入的參數可以為intstrbytesbytearray

    x1 = float(1)
    x2 = float('2')
    x3 = float(b'3')
    print(type(x1), x1)
    print(type(x2), x2)
    print(type(x3), x3)
    
    # 輸出結果如下:
    <class 'float'> 1.0
    <class 'float'> 2.0
    <class 'float'> 3.0
    
  • complex (複數類型)

    說明:由實數和虛數部分組成,都是浮點數。

    傳入參數可以為intstr,如果傳入兩參,前面一個為實數部分,後一個參數為虛數部分。

    x1 = complex(1)
    x2 = complex(2,2)
    x3 = complex('3')
    print(type(x1), x1)
    print(type(x2), x2)
    print(type(x3), x3)
    
    # 輸出結果如下:
    <class 'complex'> (1+0j)
    <class 'complex'> (2+2j)
    <class 'complex'> (3+0j)
    
  • bool (布爾類型)

    說明:為int的子類,返回的是True和False,對應的是1和0。

    x1 = bool(0)
    x2 = bool(1)
    x3 = bool()
    x4 = 2 > 1
    print(type(x1), x1)
    print(type(x2), x2)
    print(type(x3), x3)
    print(type(x4), x4)
    
    # 輸出結果如下:
    <class 'bool'> False
    <class 'bool'> True
    <class 'bool'> False
    <class 'bool'> True
    

2.2 序列(sequence)

2.2.1 list 列表

說明: 列表是由若幹元素對象組成,且是有序可變的線性數據結構,使用中括弧[ ]表示。

  • 初始化

    lst = []  # 空列表方式1
    #或者
    lst = list()  # 空列表方式2
    print(type(lst),lst)
    
    # 輸入結果如下:
    <class 'list'> []
    
  • 索引

    說明: 使用正索引(從左至右)、負索引(從右至左)訪問元素,時間複雜度為O(1),效率極高的使用方式。

    按照給定區間獲取到數據,叫做切片。

    正索引:

    從左至右,從0開始索引,區間為[0,長度-1],左包右不包。

    lst = ['a','b','c','d']
    print(lst[0])  # 獲取第一個元素
    print(lst[1:2])  # 獲取第二個元素,左包右不包,切片
    print(lst[2:])  # 獲取第三個元素到最後一個元素,切片
    print(lst[:])  # 獲取所有元素,切片
    
    # 輸出結果如下:
    a
    ['c']
    ['c', 'd']
    ['a', 'b', 'c', 'd']
    

    負索引:

    從右至左,從-1開始索引,區間為[-長度,-1]

    lst = ['a','b','c','d']
    print(lst[-1])
    print(lst[-2:])
    
    # 輸出結果如下:
    d
    ['c', 'd']
    
  • 查詢

    index( )方法:L.index(value, [start, [stop]]) -> integer

    返回的是索引id,要迭代列表,時間複雜度為O(n)。

    lst = ['a','b','c','d']
    print(lst.index('a',0,4))  # 獲取區間[0,4]的元素'a'的索引id
    
    # 輸出結果如下:
    0
    

    備註:如果查詢不到元素,則拋出ValueError

    count( ) 方法:L.count(value) -> integer

    返回的是元素出現的次數,要迭代列表,時間複雜度為O(n)。

    lst = ['a','b','a','b']
    print(lst.count('a'))
    
    # 輸出結果如下:
    2
    

    len( ) 方法:返回的是列表元素的個數,時間複雜度為O(1)。

    lst = ['a','b','c','d']
    print(len(lst))
    
    # 輸出結果如下:
    4
    

    備註:所謂的O(n) 是指隨著數據的規模越來越大,效率下降,而O(1)則相反,不會隨著數據規模大而影響效率。

  • 修改

    列表是有序可變,所以能夠對列表中的元素進行修改。

    lst = ['a','b','c','d']
    lst[0] = 'A'
    print(lst)
    
    # 輸出結果如下:
    ['A', 'b', 'c', 'd']
    
  • 增加

    append( ) 方法:L.append(object) -> None

    尾部追加元素,就地修改,返回None。

    lst = ['a','b','c','d']
    lst.append('e')
    print(lst)
    
    # 輸出結果如下:
    ['a', 'b', 'c', 'd', 'e']
    

    insert( )方法:L.insert(index, object) -> None ,

    在指定索引位置插入元素對象,返回None。

    lst = ['a','b','c','d']
    lst.insert(0,'A')  # 在索引0位置插入'A',原有的元素全部往後移,增加了複雜度
    print(lst)
    
    # 輸出結果如下:
    ['A', 'a', 'b', 'c', 'd']
    

    extend( )方法: L.extend(iterable) -> None

    可以增加多個元素,將可迭代對象的元素追加進去,返回None。

    lst = ['a','b','c','d']
    lst.extend([1,2,3])
    print(lst)
    
    # 輸出結果如下:
    ['a', 'b', 'c', 'd', 1, 2, 3]
    

    還可以將列表通過 +* ,拼接成新的列表。

    lst1 = ['a','b','c','d']
    lst2 = ['e','f','g']
    print(lst1 + lst2)
    print(lst1 * 2)  # 將列表裡面的元素各複製2份
    
    # 輸出結果如下:
    ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    ['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']
    

    這裡還有一個特別要註意情況如下:

    lst1 = [[1]] * 3  # 結果:[[1], [1], [1]]
    print(lst1)
    lst1[0][0] = 10  # 結果:[[10], [1], [1]],是這樣嘛??
    print(lst1)
    
    # 輸出結果如下:
    [[1], [1], [1]]
    [[10], [10], [10]]  # 為什麼結果會是這個?請往下看列表複製章節,找答案!
    
  • 刪除

    remove()方法:L.remove(value) -> None

    從左至右遍歷查找,找到就刪除該元素,返回None,找不到則拋出ValueError

    lst = ['a','b','c','d']
    lst.remove('d')
    print(lst)
    
    # 輸出結果如下:
    ['a', 'b', 'c']  # 元素'd'已經被刪除
    

    pop() 方法:L.pop([index]) -> item

    預設刪除尾部元素,可指定索引刪除元素,索引越界拋出IndexError

    lst = ['a','b','c','d']
    lst.pop()
    print(lst)
    
    # 輸出結果如下:
    ['a', 'b', 'c']
    

    clear() 方法:L.clear() -> None

    清空列表所有元素,慎用。

    lst = ['a','b','c','d']
    lst.clear()
    print(lst)
    
    # 輸出結果如下:
    []  # 空列表了
    
  • 反轉

    reverse( ) 方法:L.reverse()

    將列表中的元素反轉,返回None。

    lst = ['a','b','c','d']
    lst.reverse()
    print(lst)
    
    # 輸出結果如下:
    ['d', 'c', 'b', 'a']
    
  • 排序

    sort() 方法:L.sort(key=None, reverse=False) -> None

    對列表元素進行排序,預設為升序,reverse=True為降序。

    lst = ['a','b','c','d']
    lst.sort(reverse=True)
    print(lst)
    
    # 輸出結果如下:
    ['d', 'c', 'b', 'a']
    
  • in成員操作

    判斷成員是否在列表裡面,有則返回True、無則返回False。

    lst = ['a','b','c','d']
    print('a' in lst)
    print('e' in lst)
    
    # 輸出結果如下:
    True
    False
    
  • 列表複製

    說明: 列表複製指的是列表元素的複製,可分為淺copy和深copy兩種。列表元素對象如列表、元組、字典、類、實例這些歸為引用類型(指向記憶體地址),而數字、字元串先歸為簡單類型,好讓大家理解。

    示例一:這是屬於拷貝嘛?

    lst1 = [1,[2,3],4]
    lst2 = lst1
    print(id(lst1),id(lst2),lst1 == lst2, lst2)  # id() 查看記憶體地址
    
    # 輸出結果如下:
    1593751168840 1593751168840 True [1, [2, 3], 4]
    

    顯然不是屬於任何copy,說白了都是指向同一個記憶體地址。

    示例二:淺拷貝copy

    說明: 淺拷貝對於引用類型對象是不會copy的,地址指向仍是一樣。

    lst1 = [1,[2,3],4]
    lst2 = lst1.copy()
    print(id(lst1),id(lst2),lst1 == lst2, lst2)
    print('=' * 30)
    lst1[1][0] = 200  # 修改列表的引用類型,所有列表都會改變
    print(lst1, lst2)
    
    # 輸出結果如下:
    1922175854408 1922175854344 True [1, [2, 3], 4]
    ==============================
    [1, [200, 3], 4] [1, [200, 3], 4]
    

    示例三:深拷貝deepcopy

    說明: 深拷貝對於引用類型對象也會copy成另外一份,地址指向不一樣。

    import copy
    
    lst1 = [1,[2,3],4]
    lst2 = copy.deepcopy(lst1)
    print(id(lst1),id(lst2),lst1 == lst2, lst2)
    print('=' * 30)  
    lst1[1][0] = 200  # 修改列表的引用類型,不會影響其他列表
    print(lst1, lst2)
    
    # 輸出結果如下:
    2378580158344 2378580158280 True [1, [2, 3], 4]
    ==============================
    [1, [200, 3], 4] [1, [2, 3], 4]
    

2.2.2 tuple 元組

說明: 元組是由若幹元素對象組成,且是有序不可變的數據結構,使用小括弧( )表示。

  • 初始化

    t1 = ()  # 空元素方式1,一旦創建將不可改變
    t2 = tuple()  # 空元素方式2,一旦創建將不可改變
    t3 = ('a',)  # 元組只有一個元素,一定要加逗號','
    t4 = (['a','b','c'])  # 空列表方式2
    

    備註: 元組如果只有一個元素對象,一定要在後面加逗號, 否則變為其他數據類型。

  • 索引
    同列表一樣,不再過多舉例。

    t = ('a','b','c','d')
    print(t[0])
    print(t[-1])
    # 輸出結果如下:
    a
    d
    
  • 查詢

    同列表一樣,不再過多舉例。

    t = ('a','b','c','d')
    print(t.index('a'))
    print(t.count('a'))
    print(len(t))
    
    # 輸出結果如下:
    0
    1
    4
    
  • 增刪改

    元組是不可變類型,不能增刪改元素對象。

    但是要註意如下場景:

    元組中的元素對象(記憶體地址)不可變,引用類型可變。----這裡又出現引用類型的情況了。

    # 元組的元組不可修改(即記憶體地址)
    t = ([1],)
    t[0]= 100
    print(t)
    # 結果報錯了
    TypeError: 'tuple' object does not support item assignment
        
    ############################################
    
    # 元組裡面的引用類型對象可以修改(如嵌套了列表)
    t = ([1],2,3)
    t[0][0] = 100  # 對元組引用類型對象的元素作修改
    print(t)
    
    # 輸出結果如下:
    ([100], 2, 3)
    

2.2.3 string 字元串

說明: 字元串是由若幹字元組成,且是有序不可變的數據結構,使用引號表示。

  • 初始化
    多種花樣,使用單引號、雙引號、三引號等。

    name = 'tom'
    age = 18
    str1 = 'abc'  # 單引號字元串
    str2 = "abc"  # 雙引號字元串
    str3 = """I'm python"""  # 三引號字元串
    str4 = r"c:\windows\note"  # r首碼,沒有轉義(轉義字元不生效)
    str5 = f'{name} is {age} age.'  # f首碼,字元串格式化,v3.6支持
    print(type(str1), str1)
    print(type(str2), str2)
    print(type(str3), str3)
    print(type(str4), str4)
    print(type(str5), str5)
    
    # 輸出結果如下:
    <class 'str'> abc
    <class 'str'> abc
    <class 'str'> I'm python
    <class 'str'> c:\windows\note
    <class 'str'> tom is 18 age.
    
  • 索引

    同列表一樣,不再過多舉例。

    str = "abcdefg"
    print(str[0])
    print(str[-1])
    
    # 輸出結果如下:
    a
    g
    
  • 連接

    通過加號 + 將多個字元串連接起來,返回一個新的字元串。

    str1 = "abcd"
    str2 = "efg"
    print(str1 + str2)
    
    # 輸出結果如下:
    abcdefg
    

    join( ) 方法:S.join(iterable) -> str

    s表示分隔符字元串,iterable為可迭代對象字元串,結果返回字元串。

    str = "abcdefg"
    print('->'.join(str))
    
    # 輸出結果如下:
    a->b->c->d->e->f->g
    
  • 字元查找

    find( ) 方法:S.find(sub[, start[, end]]) -> int

    從左至右查找子串sub,也可指定區間,找到返回正索引,找不到則返回 -1

    str = "abcdefg"
    print(str.find('a',0,7))
    print(str.find('A'))
    
    # 輸出結果如下:
    0
    -1
    

    rfind( ) 方法:S.rfind(sub[, start[, end]]) -> int

    從右至左查找子串sub,也可指定區間,找到返回正索引,找不到則返回 -1

    str = "abcdefg"
    print(str.rfind('a'))
    print(str.rfind('A'))
    
    # 輸出結果如下:
    0
    -1
    

    還有index()find() 類似,不過找不到會拋異常,不建議使用。

    s.count() 還可以統計字元出現的次數。

    len(s) 還可以統計字元串的長度。

  • 分割

    split( ) 方法:S.split(sep=None, maxsplit=-1) -> list of strings

    sep表示分隔符,預設為空白字元串,maxsplit=-1表示遍歷整個字元串,最後返回列表。

    str = "a,b,c,d,e,f,g"
    print(str.split(sep=','))
    
    # 輸出結果如下:
    ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    

    rsplit( ) 方法與上面不同就是,從右至左遍歷。

    splitlines() 方法: S.splitlines([keepends]) -> list of strings

    按行來切割字元串,keepends表示是否保留行分隔符,最後返回列表。

    str = "a\nb\nc\r\nd"
    print(str.splitlines())
    print(str.splitlines(keepends=True))
    
    # 輸出結果如下:
    ['a', 'b', 'c', 'd']
    ['a\n', 'b\n', 'c\r\n', 'd']
    

    partition() 方法S.partition(sep) -> (head, sep, tail)

    從左至右查詢分隔符,遇到就分割成頭、分隔符、尾的三元組,返回的是一個元組tuple。

    str = "a*b*c*d"
    print(str.partition('*'))
    # 輸出結果如下:
    ('a', '*', 'b*c*d')
    

    rpartition() 方法S.rpartition(sep) -> (head, sep, tail)

    與上方法不同,就是從右至左,不過這個比較常用,可以獲取尾碼部分信息。

    str1 = "http://www.python.org:8843"
    str2 = str1.rpartition(':')
    port = str2[-1]
    print(port)
    
  • 替換

    replace() 方法:S.replace(old, new[, count]) -> str

    遍歷整個字元串,找到全部替換,count表示替換次數,預設替換全部,最後返回一個新的字元串

    str = "www.python.org"
    print(str.replace('w','m'))  # 返回的是一個新的字元串
    print(str)  # 字元串不可變,保持原樣
    
    # 輸出結果如下:
    mmm.python.org
    www.python.org
    
  • 移除

    strip() 方法:S.strip([chars]) -> str

    在字元串兩端移除指定的字元集chars , 預設移除空白字元。

    str = " * www.python.org  *"
    print(str.strip("* "))  # 去掉字元串首尾帶有星號'*' 和 空白' '
    
    # 輸出結果如下:
    www.python.org
    

    還有lstrip()rstrip 分別是移除字元串左邊和右邊字元集。

  • 首尾判斷

    startswith() 方法:S.startswith(prefix[, start[, end]]) -> bool

    預設判斷字元串開頭是否有指定的字元prefix,也可指定區間。

    str = "www.python.org"
    print(str.startswith('www',0,14))
    print(str.startswith('p',0,14))
    # 輸出結果如下:
    True
    False
    

    endswith() 方法:S.endswith(suffix[, start[, end]]) -> bool

    預設判斷字元串結尾是否有指定的字元suffix,也可指定區間。

    str = "www.python.org"
    print(str.startswith('www',0,14))
    print(str.startswith('p',0,14))
    # 輸出結果如下:
    True
    False
    
    str = "www.python.org"
    print(str.endswith('g',11,14))
    # 輸出結果如下:
    True
    
  • 格式化

    c風格格式化:

    格式字元串:使用%s(對應值為字元串),%d(對應值為數字)等等,還可以在中間插入修飾符%03d。

    被格式的值:只能是一個對象,可以是元組或是字典。

    name = "Tom"
    age = 18
    print("%s is %d age." % (name,age))
    # 輸出結果如下:
    Tom is 18 age.
    

    format格式化:

    格式字元串:使用花括弧{ }, 花括弧裡面可以使用修飾符。

    被格式的值:*args為可變位置參數,**kwargs為可變關鍵字參數。

    # 位置傳參
    print("IP={} PORT={}".format('8.8.8.8',53))  # 位置傳參
    print("{Server}: IP={1} PORT={0}".format(53, '8.8.8.8', Server='DNS Server'))  # 位置和關鍵字傳參傳參
    
    # 輸出結果如下:
    IP=8.8.8.8 PORT=53
    DNS Server: IP=8.8.8.8 PORT=53
    
    # 浮點數
    print("{}".format(0.123456789))
    print("{:f}".format(0.123456789))    #  小數點預設為6位
    print("{:.2f}".format(0.123456789))  # 取小數點後兩位
    print("{:15}".format(0.123456789))   # 寬度為15,右對齊
    
    # 輸出結果如下:
    0.123456789
    0.123457     # 為什麼是這個值?大於5要進位
    0.12
        0.123456789  # 左邊有4個空格
    
  • 其他常用函數

    str = "DianDiJiShu"
    print(str.upper())  # 字母全部轉化為大寫
    print(str.lower())  # 字母全部轉化為小寫
    
    # 輸出結果如下:
    DIANDIJISHU
    diandijishu
    

2.2.4 bytes 位元組

bytes bytearray從python3引入的兩種數據類型。

在電腦的世界里,機器是以01 組成的,也叫二進位(位元組)來通信的,這套編碼我們叫做ASCII編碼。

所以機器通信的語言就叫做機器語言。然而我們人類想要跟機器通信,那麼需要怎麼做呢?

  • 把人類的語言編碼成機器能夠識別的語言,通常叫做編碼(字元串轉換為ASCII碼)。
  • 把機器的語言解碼成人類能夠識別的語言,通常叫做解碼(ASCII碼轉換為字元串)。

至今現代編碼的發展史過程大概是這樣的:ASCII(1位元組) -> unicode(2~4位元組) -> utf-8(16位元組),utf8是多位元組編碼,一般使用13位元組,特殊使用4位元組(一般中文使用3位元組),向下相容ASCII編碼。

中國也有屬於自己的編碼:gbk

ASCII碼表常用的必須牢記(整理部分):

詳細ASCII碼下載鏈接:

鏈接:https://pan.baidu.com/s/1fWVl57Kqmv-tkjrDKwPvSw 提取碼:tuyz

所以,機器上的進位就是位元組,1位元組等於8位,例如:十進位2,用2進位和16進位表示:

# 二進位
0000 0010  # 一個位元組bytes

# 16進位,機器基本都是顯示16進位
0x2

bytes 是不可變類型

bytes()     # 空bytes,一旦創建不可改變
bytes(int)  # 指定位元組的大小,用0填充
bytes(iterable_of_ints)  # [0.255]整數的可迭代對象
bytes(string, encoding[, errors])  # 等價於string.encoding(),字元串編碼成位元組
bytes(bytes_or_buffer)  # 複製一份新的位元組對象
  • 初始化

    b1 = bytes()
    b2 = bytes(range(97,100))
    b3 = bytes(b2)
    b4 = bytes('123',encoding='utf-8')
    b5 = b'ABC'
    b6 = b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode('utf-8')
    print(b1, b2, b3, b4, b5, b6, sep='\n')
    
    # 輸出結果如下:
    b''
    b'abc'
    b'abc'
    b'123'
    b'ABC'
    你好
    

2.2.5 bytearray 位元組數組

bytearray 是可變數組,可以進行增刪改操作,類似列表。

bytearray()  # 空bytearray,可改變
bytearray(iterable_of_ints)  # [0.255]整數的可迭代對象
bytearray(string, encoding[, errors])  # 等價於string.encoding(),字元串編碼成位元組
bytearray(bytes_or_buffer)   # 複製一份新的位元組數組對象
bytearray(int)  # 指定位元組的大小,用0填充
  • 增刪改

    # 初始化
    b = bytearray()
    print(b)
    # 輸出結果如下:
    bytearray(b'')
    #--------------------------
    # 增加元素對象
    b.append(97)
    print(b)
    b.extend([98,99])
    print(b)
    # 輸出結果如下:
    bytearray(b'a')
    bytearray(b'abc')
    #--------------------------
    # 插入元素對象
    b.insert(0,65)
    print(b)
    # 輸出結果如下:
    bytearray(b'Aabc')
    #--------------------------
    # 刪除元素對象
    b.pop()
    print(b)
    # 輸出結果如下:
    bytearray(b'Aab')
    

今天就到這了,下一回合咱再接著嘮嗑 set (集合) dict (字典) ,敬請耐心等待。


如果喜歡的我的文章,歡迎關註我的公眾號:點滴技術,掃碼關註,不定期分享

公眾號:點滴技術


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

-Advertisement-
Play Games
更多相關文章
  • 前端作為互聯網時代直接觸達用戶的視窗,大到我們每天瀏覽到的網站,小到一次點擊按鈕的頁面,前端無處不在。並且在產品的眾多開發環節之中,最能讓用戶直觀感受到的就是前端開發。因而前端行業的廣闊發展前景也吸引了不少人的轉業學習。那麼,零基礎如何學好前端呢?有什麼建議嗎?本文將為初學者詳細解答一下這兩個問題, ...
  • 正常我們寫一個左右兩列,左側一列放置圖片的html,如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .container{ background-col ...
  • 在vue項目中,為了減少首屏載入的時間,通常會開啟路由的懶載入。路由懶載入配合gizp確實能幫助我們大大的加快首屏的載入時間。 然而,路由懶載入會使得我們在第一次打開一個新頁面的時候,會有一個載入時間。如果在這個時候我們沒有一個提示的話,給人的感覺會是好像我點了頁面跳轉但是沒反應。所以,這個時候我們 ...
  • 先上一張咱們的原始圖 rs7.jpg 如下: 一、mask-image屬性 1.基本的png圖遮罩展示 我們使用的遮罩圖片 ad.png,如下: html: <img src="rs7.jpg" alt="" class="mask-img"> css: .mask-img { width: 300 ...
  • 最詳細的css3選擇器解析 選擇器是什麼? 比較官方的解釋:在 CSS 中,選擇器是一種模式,用於選擇需要添加樣式的元素。 最常見的 CSS 選擇器是元素選擇器。換句話說,文檔的元素就是最基本的選擇器。 看代碼,元素選擇器就是這個: h1作為一個元素標簽,是最基本的選擇器,這樣可以對h1標簽設置屬性 ...
  • 首先保證路徑正確,引入ttf字體,沒有生效 使用線上工具把ttf轉為更多常用的字體格式 網址:https://www.fontke.com/tool/convfont/ css里補全格式: 生效了 ...
  • 導讀 轉載自 "冪等性如何實現?深入瞭解一波!!!" 現在這個時代大家可能最關心的就是錢了,那麼有沒有想過你銀行轉賬給你沒有一次是轉多的,要麼失敗,要麼成功,為什麼不能失誤一下多轉一筆呢?醒醒吧年輕人,別做夢了,做銀行的能那麼傻x嗎? 今天我們就來談一談為什麼銀行轉賬不能多給我轉一筆?關乎到錢的問題 ...
  • 功能介紹:黑貓關鍵詞URL採集工具 Pro v1.0 批量關鍵詞自動搜索採集 自動去除垃圾二級泛解析功能變數名稱 可設置是否保存功能變數名稱或者url 聯繫客服QQ:944520563 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...