Python进阶05_列表排序和查找方法

本文详细介绍了Python中两种常用的列表排序方法:list.sort()和sorted()函数,以及bisect模块的使用,包括二分查找算法和在有序序列中插入元素的方法。通过实例展示了如何利用这些工具进行高效的数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

列表中的两个排序方法

list.sort 排序

list.sort 排序直接对list本身进行排序,不会新建一个新的列表,也就是说不会复制一份原有的列表,返回只仅仅是一个None,仅仅是将list的元素进行一次排序。

Python的惯例
如果一个函数或者方法对对象进行的是就地改动,那它就应该返回
None,好让调用者知道传入的参数发生了变动,而且并未产生新的对象。例如,random.shuffle函数。

内置函数sorted 排序

sorted排序:会新建一个新的列表作为返回值,该函数可以接受的参数:

  • 受任何形式的可迭代对象
  • 不可变序列
  • 生成器

排序函数的关键字参数

reverse
  • True: 被排序的序列里的元素会以降序输出
  • False: 默认值
key
  • 一个只有一个参数的函数,这个函数会被用在序列里的每一个元素上
  • 在对一些字符串排序时,可以用 key=str.lower 来实现忽略大小写的排序
  • 用 key=len 进行基于字符串长度的排序
# 列表中的两个排序方法
fruits = ['grape', 'raspberry', 'apple', 'banana']
# 新建一个排序列表
print(sorted(fruits)) 
#原列表并未被改变
print(fruits) 
#reverse 降序
print(sorted(fruits,reverse=True)) 
#key的使用
print(sorted(fruits,key=len))
print(sorted(fruits,reverse=True,key=len))

#list.sort的使用,会改变fruits本身
print(fruits.sort())
print(fruits)

['apple', 'banana', 'grape', 'raspberry']
['grape', 'raspberry', 'apple', 'banana']
['raspberry', 'grape', 'banana', 'apple']
['grape', 'apple', 'banana', 'raspberry']
['raspberry', 'banana', 'grape', 'apple']
None
['apple', 'banana', 'grape', 'raspberry']

列表排序的管理bisect

关于bisect模块

bisect是一个模块,使用的时候需要import,标准库的 bisect模块提供了二分查找算法主要。包括两个函数:

  • bisect:利用二分查找算法来在有序序列中查找
  • insort:利用二分查找算法来在有序序列中插入元素

用bisect来搜索

bisect(haystack, needle) 在 haystack(干草垛)里搜索 needle(针)的位置,该位置满足的条件是,把 needle 插入这个位置之后,haystack 还能保持升序。

  • haystack 必须是一个有序的序列。
  • bisect(haystack, needle) 查找位置 index
  • 再用 haystack.insert(index, needle) 来插入新值。
bisect 两个调优方向
  • 首先可以用它的两个可选参数——lo 和 hi——来缩小搜寻的范围。
  • 其次,bisect 函数其实是 bisect_right 函数的别名,后者还有个姊妹函数叫 bisect_left。
    • bisect_left 返回的插入位置是原序列中跟被插入元素相等的元素的位置,新元素会被放置于它相等的元素的前面。
    • bisect_right 返回的则是跟它相等的元素之后的位置。
# 演示bisect函数搜索和插入的过程
import bisect
import sys

HAYSTACK =[1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30]
NEEDLES = [0, 1, 2, 5, 8, 10,22, 23, 29, 30, 31] 

# 打印的格式
ROW_FMT = '{0:2d} @ {1:2d}    {2}{0:<2d}'

def demo(bisect_fn):
    for needle in reversed(NEEDLES):
        # 利用bisect_fn找到要插入的位置
        position = bisect_fn(HAYSTACK,needle)
        offset = position * '  |'
        print(ROW_FMT.format(needle,position,offset))


if __name__ == '__main__':
    if sys.argv[-1] == 'left':
        bisect_fn = bisect.bisect_left
    else:
        bisect_fn = bisect.bisect
        
    print('DEMO:',bisect_fn.__name__)
    print('haystack ->',' '.join('%2d' % n for n in HAYSTACK))
    demo(bisect_fn)

DEMO: bisect
haystack ->  1  4  5  6  8 12 15 20 21 23 23 26 29 30
31 @ 14      |  |  |  |  |  |  |  |  |  |  |  |  |  |31
30 @ 14      |  |  |  |  |  |  |  |  |  |  |  |  |  |30
29 @ 13      |  |  |  |  |  |  |  |  |  |  |  |  |29
23 @ 11      |  |  |  |  |  |  |  |  |  |  |23
22 @  9      |  |  |  |  |  |  |  |  |22
10 @  5      |  |  |  |  |10
 8 @  5      |  |  |  |  |8 
 5 @  3      |  |  |5 
 2 @  1      |2 
 1 @  1      |1 
 0 @  0    0 
建立一个用数字作为索引的查询表格

可以在很长的有序序列中作为 index 的替代,用来更快地查找一个元素的位置。

# 建立一个用数字作为索引的查询表格
def grade(score,breakpoints=[60,70,80,90],grade='FDCBA'):
    i = bisect.bisect(breakpoints,score)
    return grade[i]
print([grade(score) for score in [33,80,20,70,90,79,99]])
['F', 'B', 'F', 'C', 'A', 'C', 'A']

用bisect.insort插入新元素

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

  • insort 跟 bisect 一样,有 lo 和 hi 两个可选参数用来控制查找的范围。
  • 它也有个变体叫insort_left,这个变体在背后用的是 bisect_left。
import bisect
import random

SIZE = 7
random.seed(1729)

my_list = []
for i in range(SIZE):
    new_item = random.randrange(SIZE * 2)
    bisect.insort(my_list,new_item)
    print('%2d ->' % new_item,my_list)
10 -> [10]
 0 -> [0, 10]
 6 -> [0, 6, 10]
 8 -> [0, 6, 8, 10]
 7 -> [0, 6, 7, 8, 10]
 2 -> [0, 2, 6, 7, 8, 10]
10 -> [0, 2, 6, 7, 8, 10, 10]

分享关于人工智能,机器学习,深度学习以及计算机视觉的好文章,同时自己对于这个领域学习心得笔记。想要一起深入学习人工智能的小伙伴一起结伴学习吧!扫码上车!

瓦力人工智能 - 扫码上车

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值