python基础学习之列表

 

列表的创建操作

创建空列表的两种方式

list001 = []  # 方式1:直接中括号创建,推荐使用这种方法创建
list001 = list()  # 方式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)]

列表的添加操作

在列表的尾部添加(append方法)

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

在指定的位置添加(insert方法)

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

合并列表

用 extend() 方法合并

list001 = []
list002 = []
# 将list002中所有元素追加至list001的尾部,不影响list001列表中已有元素的位置,也不影响list001在内存中的起始地址。
list001.extend(list002)  # 注意:改变的是list001,list002列表没有改变,还是原来的样子

直接相加进行合并

list001 = []
list002 = []
list003 = list001 + list002  # 注意:这种方法实际是得到一个新列表,原来的两个列表都没改变

用 sum() 方法合并

a = ['张三', {"李四": 98}, ['王五', '管理员']]
b = ['旅游', '唱歌', '跳舞']
c = [(520, 1314), {'嘻嘻', 5, 8}, 9]
d = sum((a, b, c), [])
print(d)  # 输出:['张三', {'李四': 98}, ['王五', '管理员'], '旅游', '唱歌', '跳舞', (520, 1314), {8, '嘻嘻', 5}, 9]

两个列表合并成字典

def list2_to_dict(lst1, lst2):
    """
    将两个列表合并成字典,将两个长度不等的列表合并为一个字典时,服从少数原则(相当于丢弃多余的元素)
    例:list2_to_dict([1, 2], ['a', 'b', 'c']) 结果:{1: 'a', 2: 'b'}
    """
    return dict(zip(lst1, lst2))

合并多个有序列表

heapq.merge()函数,该函数将多个排序列表作为参数,得到一个新的排序后的列表,它得到的实际是一个迭代器对象,这意味着可以利用它处理非常长的序列,而开销却非常小。

import heapq

a = [1, 3, 7, 10]
b = [2, 5, 6, 11]
res = list(heapq.merge(a, b))
print(res)  # [1, 2, 3, 5, 6, 7, 10, 11]

复制列表

浅拷贝列表

name = ["张三", "李四", "王五"]
student = ["小明", "小红", name]
# 生成列表的副本.注意:这实际上是浅拷贝,注意id值一样
student_01 = student.copy()
print(id(student[-1]))  # 2277330399296
print(id(student_01[-1]))  # 2277330399296

深拷贝列表

import copy

name = ["张三", "李四", "王五"]
student = ["小明", "小红", name]
# 生成列表的副本.注意:这是深度拷贝,注意id值不一样
deep_copy = copy.deepcopy(student)
print(id(student[-1]))  # 2277330402176
print(id(deep_copy[-1]))  # 2277330399936

列表的删除操作

根据索引进行删除

删除某一个元素(del方法)

students = ["张三", "李四", "王五", "赵六", "杰克", "汤姆", "小明"]
del students[0]

删除最后一个元素(pop方法)

students = ["张三", "李四", "王五", "赵六", "杰克", "汤姆", "小明"]
stu = students.pop()  # 将最后一个元素删除,变量stu会接收被删除的值,及stu = "小明"
# 注意:pop()方法是有返回值的,返回的就是被删除的元素,pop(-1)和pop()等价,默认删除最后一个

删除指定索引的元素

students = ["张三", "李四", "王五", "赵六", "杰克", "汤姆", "小明"]
stu = students.pop(2)  # 将索引是2的元素删除,变量stu会接收被删除的值,及stu = "王五"

根据索引列表批量删除

import numpy as np

indexes = [1, 4, 6, 8]  # 要删除的元素索引
my_list = ["北京", "莫斯科", "上海", "眉山", "洛杉矶", "成都", "多伦多", "武汉", "胡志明"]  # 原始列表

# 方式一:这种方式得到的是新列表,原列表没有改变
new_list = [n for i, n in enumerate(my_list) if i not in indexes]
print(new_list)

# 方式二:这种方式得到的是新列表,原列表没有改变
new_list = [my_list[i] for i in range(len(my_list)) if i not in indexes]
print(new_list)

# 方式三:借助numpy模块,这种方法在处理大型数据集时通常具有更好的性能
my_array = np.array(my_list)  # 创建一个numpy数组
indices_to_remove = np.array(indexes)  # 创建一个索引列表,表示要删除的元素的位置
mask = np.ones(len(my_array), dtype=bool)  # 创建一个布尔数组,表示哪些元素需要保留
mask[indices_to_remove] = False
my_array_new = my_array[mask]  # 使用布尔数组来索引原始数组,得到删除指定索引后的新数组
print(my_array_new.tolist())

# 方式四:注意,由于删除列表元素会影响后续元素的索引,因此我们需要倒序遍历要删除的元素索引。这种方式改变的是原列表
for index in sorted(indexes, reverse=True):  # 遍历要测除的元素索引,逐个删除元素
    del my_list[index]
print(my_list)

根据元素进行删除

移除指定元素(remove方法)

students = ["张三", "李四", "王五", "赵六", "杰克", "汤姆", "小明", "李四"]
# 删除第一次出现的 “李四” ,被删除的元素不存在,会抛出异常,
students.remove("李四")  # 注意,此方法没有返回值,不能用变量去接收

移除多个元素

to_remove = ["胡志明", "洛杉矶", "多伦多", "莫斯科"]  # 定义要删除的元素的列表
my_list = ["北京", "莫斯科", "上海", "眉山", "洛杉矶", "成都", "多伦多", "武汉", "胡志明"]  # 原始列表

# 方式一:使用filter函数
new_list = list(filter(lambda x: x not in to_remove, my_list))
print(new_list)
# 方式二:使用列表推导式
new_list =  [x for x in my_list if x not in to_remove]
print(new_list)

清空列表

my_list = ["北京", "莫斯科", "上海", "眉山", "洛杉矶", "成都", "多伦多", "武汉", "胡志明"]  # 原始列表
my_list.clear()  # 直接清空原列表

列表的修改操作

students = ["张三", "李四", "王五", "赵六", "杰克", "汤姆", "小明", "李四"]
students[0] = "小红"  # 将第一个位置的元素改为 “小红”, “张三” 被改为了 “小红”

列表的获取操作

获取元素的频率

使用 count() 方法获取元素的频率

students = ["张三", "李四", "王五", "赵六", "杰克", "汤姆", "小明", "李四"]
# 返回 “李四” 在学生列表中出现的次数
num = students.count("李四") # 注意:返回值是出现的次数

使用 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

获取出现频率最多的元素

lst = ["张三", "李四", "王五", "小明", "杰克", "汤姆", "小明"]
def demo04(lst):
    """获取列表中出现次数最多的元素,如果每个元素都是唯一的,则会返回第一个元素"""
    return max(lst, key=lst.count)
print(demo04(lst))  # 输出:小明

获取列表中的最值

import heapq

numbers = [6, 2, 9, 1, 5, 7]
print(heapq.nsmallest(3, numbers))  # 获取前3个最小的数
print(heapq.nlargest(3, numbers))  # 获取前三个最大的数

获取元素的索引

获取某元素的索引(index方法)

students = ["张三", "李四", "王五", "赵六", "杰克", "汤姆", "小明", "李四"]
# 返回列表中第一个值为 “李四” (列表中有两个李四)的元素的索引,若不存在该元素则抛出异常。
index = studnets.index("李四")  # 注意:返回值是索引

获取某元素的所有索引

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

# 方式二:借助numpy模块(推荐)
my_list = numpy.array([1, 2, 3, 1, 5, 4, 1, 2, 1, 2, 3, 1, 5, 4, 3, 1, 5, 4])
# 获取元素1的所有位置索引
indices = numpy.where(my_list == 1)[0]
print(indices.tolist())  # [0, 3, 6, 8, 11, 15]

列表的排序操作

排序

使用列表自身的方法进行排序(sort方法)

age = [13, 15, 21, 17, 8, 39, 27, 24, 17]
# 对列表中的元素进行原地排序,key用来指定排序规则,reverse为False(默认)表示升序,为True表示降序
age.sort() # 注意:此方法是对原列表进行排序,改变的是原列表
age.sort(reverse=True) # 降序

使用魔法方法进行排序(sorted方法)

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

冒泡排序

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)

快速排序

首先将列表的第一个作为中间值,for循环找出它小的放在一个列表,大的放在一个列表 然后递归,在将列表拼接到一起

def quick_sort(lst):
    """
    li = [1, 5, 9, 3, 3, 4, 10, -1, 0, -1]
    c = quick_sort(li)  输出:[-1, -1, 0, 1, 3, 3, 4, 5, 9, 10]
    """
    if not lst:
        return []
    else:
        temp = lst[0]
        less = [i for i in lst if i < temp]
        more = [i for i in lst[1:] if i >= temp]
        return quick_sort(less) + [temp] + quick_sort(more)

两个列表联动排序

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)

按字典键值排序

from operator import itemgetter

students = [{"name": "Alice", "age": 20}, {"name": "Bob", "age": 22}, {"name": "Charlie", "age": 20}]
sorted_students_item = sorted(students, key=itemgetter('age'))
print(sorted_students_item)  # [{'name': 'Alice', 'age': 20}, {'name': 'Charlie', 'age': 20}, {'name': 'Bob', 'age': 22}]

按对象属性排序

from operator import attrgetter

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

people = [Person("Alice", 20), Person("Bob", 22), Person("Charlie", 20)]

sorted_people_attr = sorted(people, key=attrgetter('age'))  # 等价于 sorted_people_attr = sorted(people, key=lambda x: x.age)
for person in sorted_people_attr:
    print(person.name, person.age)

分组排序

from itertools import groupby

students = [{"name": "Alice", "age": 20}, {"name": "Bob", "age": 22}, {"name": "Charlie", "age": 20}, {"name": "David", "age": 21}]

students.sort(key=lambda x: x['age'])  # 先按年龄排序
grouped_students = {k: list(v) for k, v in groupby(students, key=lambda x: x['age'])}  # 按年龄分组
for age, group in grouped_students.items():
    print(f"Age: {age}")
    for student in group:
        print(student['name'], student['age'])

倒序

使用列表自身的方法进行倒序(reverse方法)

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

使用魔法方法进行倒序(reversed方法)

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

使用切片方法进行倒序

age = [13, 15, 21, 17, 8, 39, 27, 24, 17]
age1 = age[::-1]  # 注意:这种方法没有改变原列表,返回的是一个新列表

列表的常见操作

遍历列表

使用 enumerate() 遍历列表

students = ["张三", "李四", "王五", "赵六", "杰克", "汤姆", "小明", "李四"]
for index, value in enumerate(students):
    print(index, value)

倒序遍历列表

for x in reversed(array):
    print(x)

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

分割列表

根据需要的大小分割列表

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))))))

根据列表中的某个元素进行分割

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]

根据返回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)]]

展开列表

嵌套深度只有一层进行展开

def expand_list3(lst):
    """展开列表清单,如果嵌套列表的深度只有1层,并且只想把所有元素放在一个普通列表中,可以通过下面的方法得到数据"""
    return [item for sublist in lst for item in sublist]

不知道嵌套深度进行展开

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))

使用递归方法进行展开

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

清理列表

去除无用字符串、空字符串等等

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() != '']

去除错误值

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))

列表去重

推荐的去重方式

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

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

通过for循环去重

# 通过for循环(不会改变原列表)
citys = ['上海', '广州', '上海', '成都', '上海', '上海', '北京', '上海', '广州', '北京', '上海']
ncity = []
for item in citys:
    if item not in ncity:
        ncity.append(item)
print(ncity)  # ['上海', '广州', '成都', '北京']

通过set方法去重

# set方法(改变原来顺序)
citys = ['上海', '广州', '上海', '成都', '上海', '上海', '北京', '上海', '广州', '北京', '上海']
ncitx=list(set(citys))
print(ncitx)  # ['成都', '上海', '广州', '北京']

通过count()方法统计并删除进行去重

# count()方法统计并删除,需要先排序(改变原来顺序)
citys = ['上海', '广州', '上海', '成都', '上海', '上海', '北京', '上海', '广州', '北京', '上海']
citys.sort()
for x in citys:
     while citys.count(x)>1:
         del citys[citys.index(x)]
print(citys)  # ['上海', '北京', '广州', '成都']

通过转成字典的方式去重

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

常见的其他操作

列表随机取样

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

将列表中的连续数据归类

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

数字按个、十、百、千位进行分割

def digitize(n):
    """
    将整形数字n转化为字符串后,还自动对该字符串进行了序列化分割,最后将元素应用到map的第一个参数中,转化为整形后返回
    例:digitize(123) 结果:[1, 2, 3]
    :param n:
    :return:
    """
    return list(map(int, str(n)))

判断数字和哪个边界值离的近

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))

斐波拉契数列

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

相同的键,对值求和

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))

找一个列表的所有子集

from itertools import combinations
 
students = ["张三", "李四", "王五", "赵六", "杰克", "汤姆", "小明"]
 
def demo01():
    """使用 itertools 中的 combinations 函数来查找一个集合的所有子集"""
    return list(combinations(students, 2))

 

posted on 2024-12-03 17:21  【1758872】的博客  阅读(49)  评论(0编辑  收藏  举报

导航