列表

【1758872】的博客發表於2024-09-27

1.1、列表的建立操作

1.1.1、建立空列表的兩種方式

list001 = []  # 方式1:直接中括號建立,推薦使用這種方法建立
list001 = list()  # 方式2:函式建立

1.1.2、初始化指定大小的列表

def initialize_2d_list(w, h, val=None):
    """
    根據給定的長和寬,以及初始值,返回一個二維列表。
    例:initialize_2d_list(2, 4) 結果:[[None, None], [None, None], [None, None], [None, None]]
    :param w: int型別 列表每個元素的長度
    :param h: int型別 列表的長度
    :param val: obj型別 初始值,預設為None
    :return: 二維列表
    """
    return [[val for _ in range(w)] for _ in range(h)]

1.2、列表的新增操作

1.2.1、在列表的尾部新增(append方法)

list001 = []
# 將x追加至列表的尾部,不影響列表中已有元素的位置,也不影響列表在記憶體中的起始地址。
list001.append(100)

1.2.2、在指定的位置新增(insert方法)

list001 = []
# 在列表的index位置處插入x,該位置之後的所有元素自動向後移動,索引加1。
list001.insert(0, 111)

1.2.3、合併列表

1.2.3.1、用 extend() 方法進行合併

list001 = []
list002 = []
# 將list002中所有元素追加至list001的尾部,不影響list001列表中已有元素的位置,也不影響list001在記憶體中的起始地址。
list001.extend(list002)  # 注意:改變的是list001,list002列表沒有改變,還是原來的樣子

1.2.3.2、直接相加進行合併

list001 = []
list002 = []
list003 = list001 + list002  # 注意:這種方法實際是得到一個新列表,原來的兩個列表都沒改變

1.2.3.3、用 sum() 函式合併

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8, 9]
d = sum((a,b,c), [])
print(d)  # 輸出:[1, 2, 3, 4, 5, 6, 7, 8, 9]

1.2.3.4、兩個列表合併成字典

def list2_to_dict(lst1, lst2):
    """
    將兩個列表合併成字典,將兩個長度不等的列表合併為一個字典時,服從少數原則(相當於丟棄多餘的元素)
    例:list2_to_dict([1, 2], ['a', 'b', 'c']) 結果:{1: 'a', 2: 'b'}
    """
    return dict(zip(lst1, lst2))

1.2.4、複製列表

1.2.4.1、淺複製列表

name = ["張三", "李四", "王五"]
student = ["小明", "小紅", name]
# 生成列表的副本.注意:這實際上是淺複製,注意id值一樣
student_01 = student.copy()
print(id(student[-1]))  # 2277330399296
print(id(student_01[-1]))  # 2277330399296

1.2.4.2、深複製列表

import copy

name = ["張三", "李四", "王五"]
student = ["小明", "小紅", name]
# 生成列表的副本.注意:這是深度複製,注意id值不一樣
deep_copy = copy.deepcopy(student)
print(id(student[-1]))  # 2277330402176
print(id(deep_copy[-1]))  # 2277330399936

1.3、列表的刪除操作

1.3.1、根據索引進行刪除

1.3.1.1、刪除最後一個元素(pop方法)

students = ["張三", "李四", "王五", "趙六", "傑克", "湯姆", "小明"]
stu = students.pop()  # 將最後一個元素刪除,變數stu會接收被刪除的值,及stu = "小明"
# 注意:pop()方法是有返回值的,返回的就是被刪除的元素,pop(-1)和pop()等價,預設刪除最後一個

1.3.1.2、刪除指定索引的元素

students = ["張三", "李四", "王五", "趙六", "傑克", "湯姆", "小明"]
stu = students.pop(2)  # 將索引是2的元素刪除,變數stu會接收被刪除的值,及stu = "王五"

1.3.2、根據元素進行刪除

1.3.2.1、刪除某一個元素(del方法)

students = ["張三", "李四", "王五", "趙六", "傑克", "湯姆", "小明"]
del students[0]

1.3.2.2、移除某一個元素(remove方法)

students = ["張三", "李四", "王五", "趙六", "傑克", "湯姆", "小明", "李四"]
# 刪除第一次出現的 “李四” ,被刪除的元素不存在,會丟擲異常,
students.remove("李四")  # 注意,此方法沒有返回值,不能用變數去接收

1.3.2.3、根據索引列表批次刪除對應位置的元素

def del_many_line(lst, index_lst):
    """根據給出的索引列表,批次刪除對應位置的值"""
    return [n for i, n in enumerate(lst) if i not in index_lst]

1.3.2.4、清空列表

age = [13, 15, 21, 17, 8, 39, 27, 24, 17]
age.clear()

1.4、列表的修改操作

students = ["張三", "李四", "王五", "趙六", "傑克", "湯姆", "小明", "李四"]
students[0] = "小紅"  # 將第一個位置的元素改為 “小紅”, “張三” 被改為了 “小紅”

1.5、列表的獲取操作

1.5.1、獲取元素的頻率

1.5.1.1、使用 count() 方法獲取元素的頻率

students = ["張三", "李四", "王五", "趙六", "傑克", "湯姆", "小明", "李四"]
# 返回 “李四” 在學生列表中出現的次數
num = students.count("李四") # 注意:返回值是出現的次數

1.5.1.2、使用 Counter 類獲取元素的頻率

from collections import Counter
 
def coll_list(lst):
    """
    對列表中各個元素出現的次數的統計
    使用 Python Counter 類。Python 計數器跟蹤容器中每個元素的頻數, Counter()返回字典,元素作為鍵,頻數作為值。
    另外使用 most_common()函式來獲取列表中的 出現次數最多的元素。
    """
    count = Counter(lst)
 
    # 返回列表中 b 元素出現的次數
    print(count['b'])
    # 返回列表中出現的次數最多的元素
    print(count.most_common(1))
    # 返回列表中出現的次數最多的頭兩個元素
    print(count.most_common(2))
    return count

1.5.2、獲取元素的索引

1.5.2.1、獲取某元素的索引(index方法)

students = ["張三", "李四", "王五", "趙六", "傑克", "湯姆", "小明", "李四"]
# 返回列表中第一個值為 “李四” (列表中有兩個李四)的元素的索引,若不存在該元素則丟擲異常。
index = studnets.index("李四")  # 注意:返回值是索引

1.5.2.2、獲取某元素的所有索引

def find_all_index(lst, target):
    """獲取某一元素在列表中的所有位置,返回結果是一個索引列表"""
    target_all_index = []
 
    for i in range(len(lst)):
        if lst[i] == target:
            target_all_index.append(i)
 
    return target_all_index

1.5.3、獲取出現頻率最多的元素

lst = ["張三", "李四", "王五", "小明", "傑克", "湯姆", "小明"]
def demo04(lst):
    """獲取列表中出現次數最多的元素,如果每個元素都是唯一的,則會返回第一個元素"""
    return max(lst, key=lst.count)
print(demo04(lst))  # 輸出:小明

1.6、列表的排序操作

1.6.1、排序

1.6.1.1、使用自身的 sort() 方法進行排序

age = [13, 15, 21, 17, 8, 39, 27, 24, 17]
# 對列表中的元素進行原地排序,key用來指定排序規則,reverse為False(預設)表示升序,為True表示降序
age.sort() # 注意:此方法是對原列表進行排序,改變的是原列表
age.sort(reverse=True) # 降序

1.6.1.2、使用魔法方法 sorted() 進行排序

age = [13, 15, 21, 17, 8, 39, 27, 24, 17]
age1 = sorted(age)  # 注意:sorted()是魔法方法,返回的是一個排序後的新列表,sort()方法是列表自帶的方法

1.6.1.3、氣泡排序

list001 = [2, 1, 0, 4, 7, 6, 3, 8, 9, 5]

for i in range(len(list001) - 1):
    for j in range(len(list001) - i - 1):
        if list001[j] > list001[j + 1]:
            list001[j], list001[j + 1] = list001[j + 1], list001[j]
print(list001)

1.6.1.4、兩個列表聯動排序

def demo01():
    """兩個列表一一對應,將一個列表排序,要求另一個列表隨之排序"""
    list_name01 = ['郭靖', '楊過', '張無忌', '周伯通', '楊天寶', '成是非']
    list_name02 = ['黃蓉', '小龍女', '趙敏', '瑛姑', '穆桂英', '雲羅郡主']
    zipped = zip(list_name01, list_name02)  # 打包操作
    # 排序,以序列list_name01為準基排序,得到對應的list_name02在list_name01的排序後的序列結果
    # key=lambda 元素: 元素[欄位索引],x:x[]字母可以隨意修改,排序方式按照中括號[]裡面的維度進行排序,[0]按照第一維排序,[2]按照第三維排序
    variable = sorted(zipped, key=lambda x: x[0])
    # 根據元組第0個值升序排序,若第0個值相等則根據第1個值升序排序
    # variable = sorted(zipped, key=lambda x: (x[0], x[1]))
    # 根據元組第0個值升序排序,若第0個值相等則根據第1個值降序排序
    # variable = sorted(zipped, key=lambda x: (x[0], -x[1]))
    result = zip(*variable)  # 解包操作
    # list_name01和list_name02沒變
    print(list(result))  # [('周伯通', '張無忌', '成是非', '楊天寶', '楊過', '郭靖'), ('瑛姑', '趙敏', '雲羅郡主', '穆桂英', '小龍女', '蓉兒')]
    return list(result)

1.6.2、倒序

1.6.2.1、使用列表自身的方法進行倒序(reverse方法)

age = [13, 15, 21, 17, 8, 39, 27, 24, 17]
age.reverse()  # 注意:此方法是對原列表進行倒序(及反轉列表),改變的是原列表

1.6.2.2、使用魔法方法進行倒序(reversed方法)

age = [13, 15, 21, 17, 8, 39, 27, 24, 17]
variable = reversed(age) # 注意:reversed()是魔法方法,返回的是一個倒序後的新列表,reverse()方法是列表自帶的方法

1.6.2.3、使用切片方法進行倒序

age = [13, 15, 21, 17, 8, 39, 27, 24, 17]
age1 = age[::-1]  # 注意:這種方法沒有改變原列表,返回的是一個新列表

1.7、列表的常見操作

1.7.1、遍歷列表

1.7.1.1、使用 enumerate() 遍歷列表

students = ["張三", "李四", "王五", "趙六", "傑克", "湯姆", "小明", "李四"]
for index, value in students:
    print(index, value)

1.7.1.2、倒序遍歷列表

# 倒序遍歷一個List:
for x in reversed(array):
    print(x)

for x in range(len(array)-1,-1,-1):
    print(array[x])

1.7.2、分割列表

1.7.2.1、根據需要的大小分割列表

from math import ceil

def chunk(lst, size):
    """
    對一個列表根據所需要的大小進行細分
    例:chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], 3) 結果:[[1, 2, 3], [4, 5, 6], [7, 8, 9], [0]]
    :param lst:
    :param size:
    :return:
    """
    return list(map(lambda x: lst[x * size:x * size + size], list(range(0, int(ceil(len(lst) / size))))))

1.7.2.2、根據列表中的某一個元素進行分割

from itertools import groupby

def according_to_element(lst, element):
    """
    根據列表中的某一個元素進行分割列表
    例子:
    ["張三","李四", "aa", "王五", "趙六", "小明", "aa", "傑克", "湯姆", "aa", "小蘭", "熊二", "熊大", "aa"]
    根據 aa 這個元素進行分割,得到
    [['張三', '李四'], ['王五', '趙六', '小明'], ['傑克', '湯姆'], ['小蘭', '熊二', '熊大']]
    """
    return [list(g) for k, g in groupby(lst, lambda x: x == element) if not k]

1.7.2.3、根據返回True或False來分割歸類

def bifurcate_by(lst, fn):
    """
    使用一個函式應用到一個列表的每個元素上,使這個列表被切割成兩部分。如果說,函式應用到元素上返回值為True,則該元素被切割到第一部分,否則分到第二部分。
    例:bifurcate_by(['beep', 'bop', 'foo', 'bar'], lambda x: x[0] == 'b'),結果:[['beep', 'bop', 'bar'], ['foo']]
    :param lst:
    :param fn:
    :return:
    """
    return [[x for x in lst if fn(x)], [x for x in lst if not fn(x)]]

1.7.3、展開列表

1.7.3.1、巢狀深度只有一層進行展開

def expand_list3(lst):
    """展開列表清單,如果巢狀列表的深度只有1層,並且只想把所有元素放在一個普通列表中,可以透過下面的方法得到資料"""
    return [item for sublist in lst for item in sublist]

1.7.3.2、不知道巢狀深度進行展開

from iteration_utilities import deepflatten  # pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ iteration_utilities
 
def expand_list2(lst):
    """展開列表清單,不知道列表巢狀深度,只想把所有元素放在一個列表中,可以透過下面的方法得到資料(使用第三方包實現)"""
    return list(deepflatten(lst))

1.7.3.3、使用遞迴方法進行展開

def expand_list(lst):
    """展開列表清單,如果不知道列表巢狀深度,並且只想把所有元素放在一個普通列表中,可以透過下面的方法得到資料(使用遞迴法實現,比較通用,推薦)"""
    if lst is None:
        lst = []
    res = []
    for ys in lst:
        if isinstance(ys, list):
            res.extend(expand_list(ys))
        else:
            res.append(ys)
    return res

1.7.4、清理列表

1.7.4.1、去除無用字串、空字串等等

def remove_useless_characters(lst):
    """
    去除無用字元,空字串等等
    例:remove_useless_characters(['', '\t', '\n', '\r', '\v', '\f', ' n  ', 'abc  ', ' ']) 
    結果:['n', 'abc']
    """
    return [x.strip() for x in lst if x.strip() != '']

1.7.4.2、去除錯誤值

def compact(lst):
    """
    使用 filter() 刪除列表中的錯誤值(如:False, None, 0 和 '')
    例:compact([None, 0, 1, False, '  ', 2, "", 3, 'a', 's', 34]) 結果:[1, '  ', 2, 3, 'a', 's', 34]
    """
    return list(filter(bool, lst))

1.7.5、列表去重

1.7.5.1、推薦的去重方式

citys = ['上海', '廣州', '上海', '成都', '上海', '上海', '北京', '上海', '廣州', '北京', '上海']

def remove_duplication(lst):
    """列表去重並且不改變原來元素的位置"""
    format_list = list(set(lst))
    format_list.sort(key=lst.index)
    return format_list
print(remove_duplication(citys))  # ['上海', '廣州', '成都', '北京']

1.7.5.2、透過for迴圈去重

# 透過for迴圈(不會改變原列表)
citys = ['上海', '廣州', '上海', '成都', '上海', '上海', '北京', '上海', '廣州', '北京', '上海']
ncity = []
for item in citys:
    if item not in ncity:
        ncity.append(item)
print(ncity)  # ['上海', '廣州', '成都', '北京']

1.7.5.3、透過set方法去重

# set方法(改變原來順序)
citys = ['上海', '廣州', '上海', '成都', '上海', '上海', '北京', '上海', '廣州', '北京', '上海']
ncitx=list(set(citys))
print(ncitx)  # ['成都', '上海', '廣州', '北京']

1.7.5.4、透過count()方法統計並刪除進行去重

# count()方法統計並刪除,需要先排序(改變原來順序)
citys = ['上海', '廣州', '上海', '成都', '上海', '上海', '北京', '上海', '廣州', '北京', '上海']
citys.sort()
for x in citys:
     while citys.count(x)>1:
         del citys[citys.index(x)]
print(citys)  # ['上海', '北京', '廣州', '成都']

1.7.5.5、透過轉成字典的方式去重

# 把列表轉成字典,利用字典鍵唯一的特性去重
citys = ['上海', '廣州', '上海', '成都', '上海', '上海', '北京', '上海', '廣州', '北京', '上海']
mylist = list({}.fromkeys(citys).keys())
print(mylist)  # ['上海', '廣州', '成都', '北京']

1.8、常見使用場景

1.8.1、列表隨機取樣

import random
import secrets

def random_list1(lst, ns):
    """從列表中隨機取樣,下面程式碼從給定列表中生成了 n 個隨機樣本"""
    samples = random.sample(lst, ns)
    return samples
 
def random_list2(lst, ns):
    """使用secrets庫生成隨機樣本"""
    s_rand = secrets.SystemRandom()
    samples = s_rand.sample(lst, ns)
    return samples

1.8.2、將列表中的連續資料歸類

def find_consecutive(lst):
    """
    在列表中找到連續的資料
    """
    lst01 = []
    lst02 = []
    for x in sorted(set(lst)):
        lst01.append(x)
        if x + 1 not in lst:
            if len(lst01) != 1:
                lst02.append(lst01)
            else:
                lst02.append(lst01)
            lst01 = []
    return lst02

1.8.3、數字按個、十、百、千位進行分割

def digitize(n):
    """
    將整形數字n轉化為字串後,還自動對該字串進行了序列化分割,最後將元素應用到map的第一個引數中,轉化為整形後返回
    例:digitize(123) 結果:[1, 2, 3]
    :param n:
    :return:
    """
    return list(map(int, str(n)))

1.8.4、判斷數字和哪個邊界值離的近

def clamp_number(num, a, b):
    """
    如果 num 落在 [a,b]數字範圍內,則返回num,否則返回離這個範圍最近的邊界
    例:clamp_number(2, 3, 10) 結果:3
    例:clamp_number(7, 3, 10) 結果:7
    例:clamp_number(20, 3, 10) 結果:10
    """
    return max(min(num, max(a, b)), min(a, b))

1.8.5、斐波拉契數列

def fibonacci(n):
    """非遞迴斐波那契"""
    if n <= 0:
        return [0]
    sequence = [0, 1]
    while len(sequence) <= n:
        a = sequence[len(sequence) - 1]
        b = sequence[len(sequence) - 2]
        next_value = (a + b)
        sequence.append(next_value)
    return sequence

1.8.6、相同的鍵,對值求和

def sum_by(lst, fn):
    """
    對列表中的各個字典裡相同鍵值的物件求和。
    例:sum_by([{'n': 4}, {'n': 2}, {'n': 8}], lambda v: v['n']) 結果:14
    :param lst:
    :param fn:
    :return:
    """
    return sum(map(fn, lst))

1.8.7、找一個列表的所有子集

from itertools import combinations
 
students = ["張三", "李四", "王五", "趙六", "傑克", "湯姆", "小明"]
 
def demo01():
    """使用 itertools 中的 combinations 函式來查詢一個集合的所有子集"""
    return list(combinations(students, 2))

相關文章