目录
个人主页:https://myelsa1024.blog.csdn.net/
一、zip函数的常见应用场景
zip函数在Python中有许多实用的应用场景,尤其是在处理多个列表或可迭代对象时,它提供了一种简洁而强大的方式来组合这些对象的元素,其常见的应用场景有:
1、并行迭代:当你有两个或多个列表,并且你想同时迭代它们时,zip()函数非常有用。例如,你可能有两个列表,一个包含名字,另一个包含对应的年龄,你想同时处理这两个列表中的元素。
2、字典键值对解包:在Python 3中,zip()函数经常与`*`操作符一起使用,用于字典的键值对解包,这在你需要交换字典的键和值时特别有用。
3、处理不等长的迭代器:当使用zip()函数迭代多个不等长的迭代器时,输出将仅在最短的迭代器耗尽时结束,这可以用于处理具有缺失数据的情况。
4、创建字典:你可以使用zip()函数和dict()函数来创建一个字典,其中一个列表包含键,另一个列表包含值。
5、与其他函数结合使用:zip()函数可以与Python中的其他函数(如map()、filter()、sorted()等)结合使用,以执行更复杂的操作。
6、数据预处理和转换:在数据分析和机器学习项目中,zip()函数可以用于同时处理多个特征列(例如,缩放或归一化多个特征)。
7、文件操作:在处理多个相关文件(如具有相同索引的数据和标签文件)时,zip()函数可以帮助你将它们的内容配对起来。
8、生成器表达式:你可以将zip()函数与生成器表达式结合使用,以创建更复杂的迭代器,而无需在内存中存储所有结果。
9、代码简化:在需要同时迭代多个可迭代对象的情况下,使用zip()函数可以使代码更简洁、更易读。
二、zip函数使用注意事项
在Python中使用zip()函数时,请注意以下事项:
1、返回迭代器:zip()函数返回的是一个迭代器,而不是一个列表,这意味着你只能遍历一次它的结果,除非你将其转换为列表、元组或其他可迭代对象。
2、不等长迭代器的处理:如果zip()函数中的可迭代对象长度不等,那么zip()函数将在最短的可迭代对象耗尽时停止,这可能会导致一些意料之外的行为,特别是当你期望所有迭代器的元素都被处理时。
3、与`*`运算符的结合使用:虽然zip()函数可以与`*`运算符结合使用来解包参数,但这通常不是zip()函数的常见用法,更常见的用法是使用`*`运算符与zip()函数的结果一起,将多个可迭代对象的元素作为单独的位置参数传递给函数。
4、修改元组内的值:由于zip()函数返回的是包含元组的迭代器或列表(如果你将其转换为列表),而元组是不可变的,因此你不能直接修改元组内的值,如果你需要修改元素,可以考虑将元组转换为列表。
5、内存使用:虽然zip()函数本身不会消耗大量内存(因为它是一个迭代器),但如果你将zip()函数的结果转换为列表,并且处理的数据集非常大,那么可能会消耗大量内存,在这种情况下,考虑使用其他方法来处理数据,如逐元素处理或使用生成器表达式。
6、Python版本差异:在Python 2中,zip()函数返回的是一个列表;但在Python 3中,它返回的是一个迭代器,这是Python 2和Python 3之间的一个重要区别,需要注意。
三、如何用好zip函数?
zip()函数在Python中是一个非常有用的内置函数,它允许你将多个可迭代对象(如列表、元组、字符串等)的元素打包成一个个元组,然后返回由这些元组组成的对象。为了用好zip()函数,请遵循以下建议:
1、并行迭代:当你需要同时迭代多个可迭代对象时,zip()函数非常有用,它允许你同时处理这些对象的元素。
2、处理不等长可迭代对象:默认情况下,zip()函数会在最短的可迭代对象耗尽时停止,如果你想要处理不等长的迭代器,并且希望保持较长的迭代器中剩余的元素,可以使用itertools.zip_longest()(在Python 2中是itertools.izip_longest())。
3、解压(Unzip):你可以使用zip(*...)来解压一个由元组组成的列表,或者任何形式的可迭代对象,只要它包含相同数量的元素。
4、与列表推导式结合使用:你可以将zip()与列表推导式结合使用,以创建新的数据结构或过滤数据。
5、作为字典的键和值:你可以使用zip()函数来创建一个字典,其中可迭代对象的元素作为键,另一个可迭代对象的元素作为值。
6、注意内存使用:当你处理大型数据集时,将zip()函数的结果转换为列表可能会消耗大量内存,在这种情况下,考虑使用迭代器直接处理数据,或者使用生成器表达式。
7、保持代码清晰:使用zip()函数时,确保你的代码易于阅读和理解,如果可能的话,为变量使用有意义的名称,并在必要时添加注释。
8、检查输入:在使用zip()函数之前,确保你的输入是可迭代的,并且长度是预期的,这有助于避免在运行时出现错误。
9、与map()函数结合使用:虽然zip()和map()在功能上有所不同,但你可以将它们结合使用来处理多个可迭代对象的元素。例如,你可以使用map()函数对每个元组应用一个函数。
1、zip函数:
1-1、Python:
# 1.函数:zip
# 2.功能:
# 2-1、无实参:用于创建空的迭代器
# 2-2、有实参:用于将可迭代对象打包成元组
# 3.语法:zip([*iterables, strict=False])
# 4.参数:
# 4-1、*iterables(可选):一个位置参数,表示任意数量的可迭代对象,如列表、字典、元组、字符串等,zip()函数允许多个可迭代对象作为参数
# 4-2、strict(可选):迭代停止条件,默认为False,即作为迭代器对象的长度可以不一样;若设置为True,则要求所有的迭代器对象必须等长
# 5.返回值:
# 5-1、无实参:返回空的迭代器
# 5-2、有实参:返回一个可迭代的zip对象,其内部元素为元组
# 6.说明:
# 6-1、如果未指定strict=True参数,所有导致可迭代对象长度不同的错误都会被抑制,这可能会在程序的其他地方表现为难以发现的错误
# 7.示例:
# 用dir()函数获取该函数内置的属性和方法
print(dir(zip))
# ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__',
# '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__',
# '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']
# 用help()函数获取该函数的文档信息
help(zip)
# 应用一:并行迭代
# 示例1: 迭代两个列表
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
for item1, item2 in zip(list1, list2):
print(f'{item1}, {item2}')
# 1, a
# 2, b
# 3, c
# 示例2: 迭代多个列表
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
list3 = ['one', 'two', 'three']
for item1, item2, item3 in zip(list1, list2, list3):
print(f'{item1}, {item2}, {item3}')
# 1, a, one
# 2, b, two
# 3, c, three
# 示例3: 列表长度不同时的处理
from itertools import zip_longest
list1 = [1, 2, 3]
list2 = ['a', 'b']
for item1, item2 in zip_longest(list1, list2, fillvalue='-'):
print(f'{item1}, {item2}')
# 1, a
# 2, b
# 3, -
# 示例4: 使用字典解压来并行迭代
names = ['Myelsa', 'Bruce', 'Jimmy']
ages = [18, 6, 15]
for name, age in zip(names, ages):
print(f'{name} is {age} years old.')
# 或者使用字典解压
for name, age in zip(names, ages):
person = {'name': name, 'age': age}
print(f'{person["name"]} is {person["age"]} years old.')
# Myelsa is 18 years old.
# Bruce is 6 years old.
# Jimmy is 15 years old.
# Myelsa is 18 years old.
# Bruce is 6 years old.
# Jimmy is 15 years old.
# 应用二:字典键值对解包
# 示例1: 迭代字典的键和值
# 假设我们有一个字典
d = {'a': 1, 'b': 2, 'c': 3}
# 使用items()方法直接迭代键和值
for key, value in d.items():
print(f'Key: {key}, Value: {value}')
# 如果非要使用zip(),可以这样做(但通常不推荐)
keys, values = zip(*d.items())
for key, value in zip(keys, values):
print(f'Key: {key}, Value: {value}')
# 注意:上述zip()用法是不必要的,因为它没有提供任何额外的好处
# 并且如果字典很大,它还会消耗额外的内存来存储keys和values元组
# Key: a, Value: 1
# Key: b, Value: 2
# Key: c, Value: 3
# Key: a, Value: 1
# Key: b, Value: 2
# Key: c, Value: 3
# 示例2: 使用zip()将字典的键和值与其他可迭代对象组合
# 原始字典的键
keys = ['a', 'b', 'c']
# 另一个列表的值
values = [1, 2, 3]
# 使用zip()将键和值组合成一个元组的迭代器
key_value_pairs = zip(keys, values)
# 将元组迭代器转换为字典
new_dict = dict(key_value_pairs)
print(new_dict)
# {'a': 1, 'b': 2, 'c': 3}
# 示例3: 解包字典的键和值到函数参数中
def process_key_value(key, value):
print(f'Processing key: {key}, value: {value}')
# 字典
d = {'a': 1, 'b': 2, 'c': 3}
# 迭代字典的项并将它们作为参数传递给函数
for key, value in d.items():
process_key_value(key, value)
# Processing key: a, value: 1
# Processing key: b, value: 2
# Processing key: c, value: 3
# 应用三:处理不等长的迭代器
# 使用zip迭代这些列表(注意:不会处理不等长)
from itertools import zip_longest
# 定义不等长的迭代器
list1 = [1, 2, 3]
list2 = ['a', 'b']
list3 = ['x', 'y', 'z', 'w']
# 使用zip_longest迭代这些列表,并为较短的列表填充默认值(例如None)
for item1, item2, item3 in zip_longest(list1, list2, list3, fillvalue='-'):
print(f'{item1}, {item2}, {item3}')
# 1, a, x
# 2, b, y
# 3, -, z
# -, -, w
for item1, item2, item3 in zip(list1, list2, list3):
print(f'{item1}, {item2}, {item3}')
# 1, a, x
# 2, b, y
# 注意:'z'和'w'没有被打印出来,因为zip在最短的列表耗尽时停止了
# 应用四:创建字典
# 定义两个列表,一个作为键,一个作为值
keys = ['a', 'b', 'c']
values = [1, 2, 3]
# 使用zip()将键和值组合成元组的迭代器
key_value_pairs = zip(keys, values)
# 将元组迭代器转换为字典
dictionary = dict(key_value_pairs)
# 打印创建的字典
print(dictionary)
# {'a': 1, 'b': 2, 'c': 3}
# 应用五:与其他函数结合使用
# 示例1: 与sorted()结合进行排序
keys = ['c', 'a', 'b']
values = [3, 1, 2]
# 使用zip()将键和值组合成一个元组的列表,然后根据键进行排序
sorted_items = sorted(zip(keys, values), key=lambda item: item[0])
# 解包排序后的元组列表回两个单独的列表
sorted_keys, sorted_values = zip(*sorted_items)
# 如果需要列表而不是元组迭代器,可以转换为列表
sorted_keys = list(sorted_keys)
sorted_values = list(sorted_values)
print(sorted_keys)
print(sorted_values)
# ['a', 'b', 'c']
# [1, 2, 3]
# 示例2: 与filter()结合进行过滤
keys = ['a', 'b', 'a', 'c']
values = [1, 2, 3, 4]
# 使用filter()和lambda表达式过滤出键为'a'的元素对
filtered_items = filter(lambda item: item[0] == 'a', zip(keys, values))
# 将过滤后的迭代器转换为列表(如果需要)
filtered_items_list = list(filtered_items)
print(filtered_items_list)
# [('a', 1), ('a', 3)]
# 示例3: 与map()结合进行映射
keys = ['a', 'b', 'c']
values = [1, 2, 3]
# 使用map()和lambda表达式将键和值相加(这里只是一个示例,通常键和值类型不同不会相加)
# 但在实际应用中,你可以执行任何你需要的操作
result = map(lambda item: item[0] + str(item[1]), zip(keys, values))
# 将map对象转换为列表(如果需要)
result_list = list(result)
print(result_list)
# ['a1', 'b2', 'c3']
# 示例4: 与列表推导式结合使用
keys = ['a', 'b', 'c']
values = [1, 2, 3]
# 使用列表推导式将键和值组合成字符串,并创建一个新列表
combined = [f"{key}:{value}" for key, value in zip(keys, values)]
print(combined)
# ['a:1', 'b:2', 'c:3']
# 应用六:数据预处理和转换
# 示例1: 将两个列表中的元素合并成字典列表
names = ['Myelsa', 'Bruce', 'Jimmy']
ages = [18, 6, 15]
# 使用 zip() 和列表推导式合并两个列表为字典列表
people = [{'name': name, 'age': age} for name, age in zip(names, ages)]
print(people)
# [{'name': 'Myelsa', 'age': 18}, {'name': 'Bruce', 'age': 6}, {'name': 'Jimmy', 'age': 15}]
# 示例2: 对两个列表中的元素进行数值转换
prices = [100, 200, 300]
discount_rates = [0.1, 0.15, 0.2]
# 使用zip()和列表推导式计算折扣价格
discounted_prices = [price * (1 - discount_rate) for price, discount_rate in zip(prices, discount_rates)]
print(discounted_prices)
# [90.0, 170.0, 240.0]
# 示例3: 将两个列表中的字符串连接成新的字符串列表
first_names = ['Myelsa', 'Bruce', 'Jimmy']
last_names = ['Smith', 'Johnson', 'Brown']
# 使用zip()和列表推导式连接字符串
full_names = [first + ' ' + last for first, last in zip(first_names, last_names)]
print(full_names)
# ['Myelsa Smith', 'Bruce Johnson', 'Jimmy Brown']
# 示例4: 合并多个列表为元组列表
names = ['Myelsa', 'Bruce', 'Jimmy']
ages = [18, 6, 15]
cities = ['Guangzhou', 'Foshan', 'Los Angeles']
# 使用zip()和列表推导式合并多个列表为元组列表
person_info = [(name, age, city) for name, age, city in zip(names, ages, cities)]
print(person_info)
# [('Myelsa', 18, 'Guangzhou'), ('Bruce', 6, 'Foshan'), ('Jimmy', 15, 'Los Angeles')]
# 应用七:文件操作
# 文件名列表
filenames = ['file.txt', 'test.txt']
# 使用with open语句来确保文件在使用后正确关闭
# 使用zip函数来同时读取每个文件的行
with open(filenames[0], 'r') as file1, open(filenames[1], 'r') as file2:
# 使用zip函数将两个文件对象(它们是可迭代的行)组合在一起
for line1, line2 in zip(file1, file2):
# 去除行尾的换行符(如果需要的话)
line1 = line1.strip()
line2 = line2.strip()
# 打印或处理每对行
print(f"从 file.txt 读取: {line1}")
print(f"从 test.txt 读取: {line2}")
print() # 打印一个空行以便区分不同的行对
# 当 with 语句块结束时,文件将自动关闭
# 从 file.txt 读取: 11
# 从 test.txt 读取: 24
#
# 从 file.txt 读取: 22
# 从 test.txt 读取: 32
#
# 从 file.txt 读取: 33
# 从 test.txt 读取: 46
import itertools
filenames = ['file.txt', 'test.txt']
with open(filenames[0], 'r') as file1, open(filenames[1], 'r') as file2:
for line1, line2 in itertools.zip_longest(file1, file2, fillvalue=''):
line1 = line1.strip() if line1 else '(无内容)'
line2 = line2.strip() if line2 else '(无内容)'
print(f"从 file1.txt 读取: {line1}")
print(f"从 file2.txt 读取: {line2}")
print()
# 从 file1.txt 读取: 11
# 从 file2.txt 读取: 24
#
# 从 file1.txt 读取: 22
# 从 file2.txt 读取: 32
#
# 从 file1.txt 读取: 33
# 从 file2.txt 读取: 46
#
# 从 file1.txt 读取: (无内容)
# 从 file2.txt 读取: 58
# 应用八:生成器表达式
# 示例1: 合并两个迭代器并生成元组
# 定义两个迭代器
iter1 = range(1, 4)
iter2 = range(10, 13)
# 使用zip()和生成器表达式(这里实际上不需要,因为zip()已经是一个迭代器)
zipped = zip(iter1, iter2)
# 遍历结果
for item in zipped:
print(item)
# (1, 10)
# (2, 11)
# (3, 12)
# 示例2: 使用生成器表达式扩展zip()的结果
# 定义两个迭代器
iter1 = ['a', 'b', 'c']
iter2 = [1, 2, 3]
# 使用zip()和生成器表达式来转换结果
formatted_items = (f"({item1}, {item2})" for item1, item2 in zip(iter1, iter2))
# 遍历结果
for item in formatted_items:
print(item)
# (a, 1)
# (b, 2)
# (c, 3)
# 示例3: 处理不同长度的迭代器并填充缺失值
import itertools
# 定义两个不同长度的迭代器
iter1 = ['a', 'b', 'c', 'd']
iter2 = [1, 2, 3]
# 使用itertools.zip_longest()和生成器表达式来处理不同长度的迭代器
filled_items = (f"({item1 or 'None'}, {item2 or 'None'})" for item1, item2 in
itertools.zip_longest(iter1, iter2, fillvalue='None'))
# 遍历结果
for item in filled_items:
print(item)
# (a, 1)
# (b, 2)
# (c, 3)
# (d, None)
# 应用九:代码简化
# 示例1: 合并两个列表并解压为变量
# 不使用zip()
list1 = ['a', 'b', 'c']
list2 = [1, 2, 3]
for i in range(len(list1)):
print(f"list1: {list1[i]}, list2: {list2[i]}")
# 使用zip()简化
for item1, item2 in zip(list1, list2):
print(f"list1: {item1}, list2: {item2}")
# list1: a, list2: 1
# list1: b, list2: 2
# list1: c, list2: 3
# list1: a, list2: 1
# list1: b, list2: 2
# list1: c, list2: 3
# 示例2: 合并多个列表为字典
# 不使用zip()
keys = ['a', 'b', 'c']
values = [1, 2, 3]
dictionary = {}
for i in range(len(keys)):
dictionary[keys[i]] = values[i]
# 使用zip()简化
dictionary = dict(zip(keys, values))
print(dictionary)
# {'a': 1, 'b': 2, 'c': 3}
# 示例3: 交换列表中的元素位置
# 原始列表
list1 = ['a', 'b', 'c']
list2 = [1, 2, 3]
# 使用zip()交换元素位置(这里只是打印结果,实际并未交换列表)
for item1, item2 in zip(list1, list2):
print(f"Original: ({item1}, {item2}), Swapped: ({item2}, {item1})")
# 如果真的想要交换两个列表的元素并存储到新的列表中
swapped_list1, swapped_list2 = zip(*zip(list2, list1))
swapped_list1, swapped_list2 = list(swapped_list1), list(swapped_list2)
print(swapped_list1)
print(swapped_list2)
# Original: (a, 1), Swapped: (1, a)
# Original: (b, 2), Swapped: (2, b)
# Original: (c, 3), Swapped: (3, c)
# [1, 2, 3]
# ['a', 'b', 'c']
# 示例4: 遍历多个列表并找出最长的字符串
# 多个列表
lists = [['apple', 'banana'], ['cat', 'dog', 'elephant'], ['fish']]
# 使用zip()和max()找出每个列表中的最长字符串(但zip()在这里并不直接有用,因为它会截断到最短列表的长度)
longest_strings = [max(lst, key=len) for lst in lists]
print(longest_strings)
# 如果我们确实想要用zip()来处理(尽管不推荐,因为会截断),可以这样做:
# 注意:这只会给出最短列表中的最长字符串,因为zip()会停止在最短的迭代器结束处
longest_in_zip = [max(tup, key=len) for tup in zip(*lists)]
print(longest_in_zip)
# ['banana', 'elephant', 'fish']
# ['apple']
1-2、VBA:
略,待后补。
2、推荐阅读:
2-1、Python-VBA函数之旅-enumerate()函数
Python算法之旅:Algorithms
Python函数之旅:Functions