遍历列表与字典
遍历列表的方法
遍历列表有两种情况,如果只需要值,那么最好直接用for循环
my_list = ["a", "b", "c", "d", "e"]
for i in my_list:
print(i)
如果还需要索引,那么最好用enumerate结合for循环
my_list = ["a", "b", "c", "d", "e"]
for index, value in enumerate(my_list):
print(index, value)
遍历字典的方法
遍历字典可能有三种情况,如果只需要键
my_dict = {"a": 1, "b": 2, "c": 3}
for key in my_dict:
print(key)
如果只需要值
my_dict = {"a": 1, "b": 2, "c": 3}
for value in my_dict.values():
print(value)
如果同时需要键和值
my_dict = {"a": 1, "b": 2, "c": 3}
for key, value in my_dict.items():
print(key, value)
遍历列表的其他方法
实际上,单纯的遍历,有很多种方法,可能是奇奇怪怪的,通常不是很好用
使用索引,这个方法在过去可能是一个非常常见的做法,但是实际上,它远不如enumerate清晰
my_list = ["a", "b", "c", "d", "e"]
for i in range(len(my_list)):
print(my_list[i])
如果将for循环改为传统的while循环,也可以算是一种“方法”,但是实际上,只是语法区别而已,通常没有必要这样做
my_list = ["a", "b", "c", "d", "e"]
i = 0
while i < len(my_list):
print(my_list[i])
i += 1
迭代器的使用也是一种可能,不过对于遍历列表的需求来说,可能不常这样做
my_list = ["a", "b", "c", "d", "e"]
iterator = iter(my_list)
while True:
try:
item = next(iterator)
print(item)
except StopIteration:
break
遍历字典的其他方法
对于字典来说,如果使用列表推导式,也可以将字典的键/值转为列表,然后就变成了一个列表遍历的问题了
my_dict = {"a": 1, "b": 2, "c": 3}
keys = [key for key in my_dict]
values = [value for value in my_dict.values()]
items = [(key, value) for key, value in my_dict.items()]
print(keys)
print(values)
print(items)
当然,也可以使用迭代器,不过这种做法可能同样少见
my_dict = {"a": 1, "b": 2, "c": 3}
dict_iterator = iter(my_dict)
while True:
try:
key = next(dict_iterator)
print(key, my_dict[key])
except StopIteration:
break
推导式
列表推导式
列表推导式的格式:[表达式 for 项目 in 可迭代对象 if 条件]
,其中if条件可选
例如,将字符串列表的所有字符串转换为大写
fruits = ["apple", "banana", "peach"]
uppercase_fruits = [fruit.upper() for fruit in fruits]
print(uppercase_fruits) # 结果为:['APPLE', 'BANANA', 'PEACH']
例如,选出列表中所有的偶数
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
even_numbers = [x for x in numbers if x % 2 == 0]
print(even_numbers) # 结果为:[2, 4, 6, 8]
列表推导式可以嵌套使用,用于处理复杂的数据结构
例如,创建3*3的矩阵
matrix = [[j for j in range(1, 4)] for i in range(1, 4)]
print(matrix) # 结果为:[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
列表推导式的好处是简洁明了,等价于传统的for循环,例如
fruits = ["apple", "banana", "peach"]
uppercase_fruits = list()
for i in fruits:
uppercase_fruits.append(i.upper())
print(uppercase_fruits)
字典推导式
字典推导式与列表推导式非常相似,格式为:{键表达式: 值表达式 for 项目 in 可迭代对象 if 条件}
例如,创建一个字典,标记单词的长度
fruits = ["apple", "banana", "peach"]
fruits_dict = {fruit: len(fruit) for fruit in fruits}
print(fruits_dict) # 结果为:{'apple': 5, 'banana': 6, 'peach': 5}
例如,交换字典的键值
original_dict = {"a": 1, "b": 2, "c": 3}
swapped_dict = {value: key for key, value in original_dict.items()}
print(swapped_dict) # 结果为:{1: 'a', 2: 'b', 3: 'c'}
生成器表达式
生成器表达式与列表推导式或者字典表达式类似,但是区别在于,生成器表达式只会“惰性”生成元素,而不会一次性生成所有元素。生成器表达式的格式只需要将列表表达式的方括号,改为圆括号即可。
生成器表达式的最大好处是,一次性占用的内存很少
import sys
# 使用列表推导式创建列表
squares_list = [x**2 for x in range(1, 1000000)]
print(f"列表大小:{sys.getsizeof(squares_list)}bytes") # 结果可能为:8448728bytes
# 使用生成器表达式创建生成器
squares_gen = (x**2 for x in range(1, 1000000))
print(f"生成器大小:{sys.getsizeof(squares_gen)}bytes") # 结果可能为:104bytes
所以说,生成器表达式有特殊的好处,特别适合用于处理大数据集或者无限序列。需要注意的是:生成器是一次性的,迭代后无法重用,如果需要重用,那么需要重新创建或者使用列表。
迭代器与生成器
基本概念
可迭代对象(Iterable):可迭代对象是可以迭代的对象,其可以返回一个迭代器,也就是可以逐个返回其内部元素的对象,常见的列表,元组,字符串,字典,集合,文件对象,生成器,迭代器都是可迭代对象。
迭代器(Iterator):迭代器是实现了__iter__()
与__next__()
方法的对象,迭代器可以记住遍历的位置,每次调用next方法,都可以得到下一个元素,当没有元素的时候,会抛出StopIteration
异常,迭代器只能往前遍历,不能后退。
生成器(Generator):生成器是特殊的迭代器,通常使用简单的函数语法与yield关键字就可以创建,调用生成器函数会返回一个生成器对象。
判断可迭代对象:
from collections.abc import Iterable
isinstance([1, 2, 3], Iterable)
isinstance(100, Iterable)
with open("1.txt") as f:
isinstance(f, Iterable) # 文件对象也是可迭代对象
实际上,for循环就是通过迭代器来完成遍历的,当遇到StopIteration
时停止。
迭代器
为你的类定义__iter__
以及__next__
就可以实现迭代器。
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.data):
raise StopIteration
result = self.data[self.index] * 2
self.index += 1
return result
it = MyIterator([1, 2, 3, 4])
for i in it:
print(i)
生成器
使用简单的函数语法与yield关键字就可以创建生成器,例如,斐波那契数列就是一个常见的例子
def fibonacci(n):
a, b = 0, 1
for i in range(n):
yield a
a, b = b, a + b
fib = fibonacci(10)
for i in fib:
print(i)
P.S. 英文单词yield的意思是,“产生”,“产出”。