本篇文章汇总了 Python 当中列表的高效用法,主要包括:对列表进行切片、通过*操作符对列表进行解包、通过key参数制定sort函数的排序方法。
1. 对列表进行切片
切片是Python中的一个强大的特性,可以用来获取序列的子序列。 使用切片的建议: 1. 从头或尾开始切片时,不要使用 0 或- 1 作为索引,直接使用空值即可。 2. 切片允许起始位置和结束位置越界,不会报错,所以不用担心切片是否真有这么多元素。 3. 可以使用赋值运算符给切片赋值,但可能会改变原列表的长度。
a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print('First four:', a[:4]) # 从起始到第4个元素,不包括a[4]
print('Last four:', a[-4:]) # 从倒数第4个元素到最后
print('Middle two:', a[3:5]) # 元素:a[3], a[4]
print('All elements:', a[:20]) # 所有元素。尽管列表a的个数小于20个,但是不会报错
# 切片的赋值。切片可以被赋值
# 如果赋值运算符的右侧个数与切片的长度不同,切片的长度会改变
a[2:7] = [99, 22, 14]
print(a) # ['a', 'b', 99, 22, 14, 'h']
# 切片赋值也可以删除元素
a[2:3] = [11, 12, 13]
print(a) # ['a', 'b', 11, 12, 13, 22, 14, 'h']
# 起止位置都为空,相当于复制整个列表
b = a[:]
assert b == a and b is not a
2. 使用 * 对列表进行解包操作
为了将一个列表分成几部分,通常的做法是使用下标和切片操作符,但是这种方法很容易出错。
当需要把一个列表顺序地分为几部分时(例如,取出前两个元素以及剩余的元素),可以使用 * 操作符来接收多余的元素。
这种带星号的表达式可以出现赋值运算符左侧的任意位置,它总是会形成一份含有零个或多个值的列表。需要注意的是,带星号的表达式只能出现一次。
def generate_csv():
yield ('Date', 'Make', 'Model', 'Year', 'Price')
yield ('2020-01-01', 'Tesla', 'Model S', '2019', 79999)
yield ('2025-01-02', 'Tesla', 'Model L', '2019', 99999)
def main():
it = generate_csv()
header, *rows = it
print('CSV Header:', header)
print('CSV Rows:', rows)
print('Row count:', len(rows))
if __name__ == '__main__':
main()
输出:
CSV Header: ('Date', 'Make', 'Model', 'Year', 'Price')
CSV Rows: [('2020-01-01', 'Tesla', 'Model S', '2019', 79999), ('2025-01-02', 'Tesla', 'Model L', '2019', 99999)]
Row count: 2
3. 通过 key 关键字参数给 sort 函数制定排序方法
内置的列表类型提供了名为 sort 方法,可以根据多项指标给 list 实例中的元素排序。默认情况下,sort 方法总是按照自然升序排列列表内的元素。例如,对于整数,自然升序是从小到大;对于字符串,自然升序是按照字母表顺序。
凡是具备自然顺序的内置类型几乎都可以使用 sort 方法排序,例如整数、浮点数、字符串等。
但是,对于自定义类型,必须给 sort 方法的 key 参数提供一个排序函数,以便告诉Python如何对自定义类型的实例进行排序。
如果排序时多个指标之间有优先级,可以把它们放在一个元组当中,让 key 返回这样的元组。对于支持一元减操作符的类型来说,可以单独给这项指标取反,让排序算法在这项指标上按照相反的方向处理。
如果这些指标不支持一元减操作符,可以多次调用 sort 方法,并在每次调用时分别指定 key 函数与 reverse 参数。最次要的指标放在第一轮处理,然后逐步处理更为重要的指标,首要指标放在最后一轮处理。
def sort_nums(numbers):
return numbers.sort()
class Tool:
def __init__(self, name, weight):
self.name = name
self.weight = weight
def __repr__(self):
return f'Tool({self.name!r}, {self.weight})'
def sort_tools_by_name(tools):
tools.sort(key=lambda x: x.name)
def sort_tools_by_weight(tools):
tools.sort(key=lambda x: x.weight)
def sort_tools_by_weight_name(tools):
tools.sort(key=lambda x: (x.weight, x.name))
def sort_tools_by_reverse_weight_name(tools):
tools.sort(key=lambda x: (-x.weight, x.name))
def sort_tools_by_reverse_name_weight(tools):
tools.sort(key=lambda x: x.weight)
tools.sort(key=lambda x: x.name, reverse=True)
def main():
nums = [3, 5, 1, 4, 2]
print('Unsorted numbers:', nums)
sort_nums(nums)
print('Sorted numbers:', nums)
print()
tools = [
Tool('hammer', 3.5),
Tool('screwdriver', 0.5),
Tool('chisel', 1.25),
Tool('file', 0.75),
Tool('saw', 0.5),
]
print('Unsorted:', repr(tools))
# Unsorted: [Tool('hammer', 3.5), Tool('screwdriver', 0.5), Tool('chisel', 1.25), Tool('file', 0.75), Tool('saw', 0.5)]
print()
sort_tools_by_name(tools)
print('Sorted by name:', tools)
# Sorted by name: [Tool('chisel', 1.25), Tool('file', 0.75), Tool('hammer', 3.5), Tool('saw', 0.5), Tool('screwdriver', 0.5)]
print()
sort_tools_by_weight(tools)
print('Sorted by weight:', tools)
# Sorted by weight: [Tool('saw', 0.5), Tool('screwdriver', 0.5), Tool('file', 0.75), Tool('chisel', 1.25), Tool('hammer', 3.5)]
print()
sort_tools_by_weight_name(tools)
print('Sorted by weight, name:', tools)
# Sorted by weight, name: [Tool('saw', 0.5), Tool('screwdriver', 0.5), Tool('file', 0.75), Tool('chisel', 1.25), Tool('hammer', 3.5)]
print()
sort_tools_by_reverse_weight_name(tools)
print('Sorted by weight in reverse, name:', tools)
# Sorted by weight in reverse, name: [Tool('hammer', 3.5), Tool('chisel', 1.25), Tool('file', 0.75), Tool('saw', 0.5), Tool('screwdriver', 0.5)]
print()
sort_tools_by_reverse_name_weight(tools)
print('Sorted by name in reverse, weight:', tools)
# Sorted by name in reverse, weight: [Tool('screwdriver', 0.5), Tool('saw', 0.5), Tool('hammer', 3.5), Tool('file', 0.75), Tool('chisel', 1.25)]
print()
if __name__ == '__main__':
main()