关于python:Python迭代器生成器分享贴近实际运维开发场景的小案例

4次阅读

共计 2904 个字符,预计需要花费 8 分钟才能阅读完成。

迭代器 & 生成器

在 Python 中,迭代器和生成器都是用来遍历数据汇合的工具,能够按需一一生成或返回数据,从而防止一次性加载整个数据汇合所带来的性能问题和内存耗费问题。

具体来说,迭代器是一个蕴含 iter() 和 next() 办法的对象,它通过 next() 办法顺次返回数据汇合中的每个元素,直到没有元素时引发 StopIteration 异样。迭代器能够自定义,也能够应用 Python 内置的可迭代对象,如列表、元组、字典、汇合等,以及内置的迭代器函数,如 zip()、map()、filter() 等。

而生成器是一种非凡的迭代器,它应用 yield 关键字来定义,能够在须要时生成数据,从而实现按需生成、惰性计算的成果。生成器能够大大简化代码,进步性能和可读性,也能够通过生成器表达式疾速创立简略的生成器。

上面分享几个贴近理论运维开发工作中的场景案例。

实战案例

  1. 假如须要从一个十分大的数据汇合中查找满足特定条件的元素,并且只须要找到第一个符合条件的元素即可进行查找。如果间接遍历整个数据汇合,可能会导致性能问题。这时能够应用迭代器和生成器来解决这个问题。
def find_first_match(data, condition):
    for item in data:
        if condition(item):
            return item
    raise ValueError('No matching item found')

large_data = [i for i in range(10000000)]  # 结构一个大数据汇合
match = find_first_match(large_data, lambda x: x > 1000)  # 查找第一个大于 1000 的元素
print(match)
  1. 假如要实现一个函数,它承受一个字符串列表,而后返回这些字符串中所有字符的呈现次数。能够应用迭代器和生成器来防止遍历整个列表,并缩小内存使用量。
def char_count(words):
    counts = {}
    for word in words:
        for char in word:
            counts[char] = counts.get(char, 0) + 1
    return counts

def char_count_lazy(words):
    def char_gen(words):
        for word in words:
            for char in word:
                yield char
    counts = {}
    for char in char_gen(words):
        counts[char] = counts.get(char, 0) + 1
    return counts
  1. 须要遍历一个多级嵌套的 JSON 对象,查找其中某个特定的值。假如 JSON 对象很大,因而不能一次性加载到内存中。这时能够应用生成器来逐级遍历 JSON 对象。
def find_value(json_obj, target_key):
    if isinstance(json_obj, dict):
        for key, value in json_obj.items():
            if key == target_key:
                yield value
            else:
                yield from find_value(value, target_key)
    elif isinstance(json_obj, list):
        for item in json_obj:
            yield from find_value(item, target_key)

json_data = {
    "name": "tantianran",
    "age": 30,
    "cars": [{"model": "BMW", "year": 2000},
        {"model": "Tesla", "year": 2020}
    ],
    "location": {
        "address": "123 Main St",
        "city": "New York",
        "state": "NY"
    }
}

for value in find_value(json_data, "year"):
    print(value)
  1. 如果须要读取一个十分大的文件,并对其中的每一行进行解决,然而因为文件太大,无奈一次性将整个文件读入内存中。这时能够应用生成器来实现逐行读取文件并逐行解决的操作。
def process_lines(file_name):
    with open(file_name) as f:
        for line in f:
            # 对每一行进行解决,这里只是简略地打印进去
            print(line.strip())

large_file = 'data.txt'
process_lines(large_file)
  1. 假如有一个大型日志文件,其中蕴含了数千万行日志记录。须要对这个日志文件进行剖析,找出所有蕴含特定关键字的日志记录,并进行统计。如果间接读取整个日志文件到内存中,可能会导致内存不足的问题。这时能够应用迭代器和生成器来解决这个问题。
def log_file_reader(log_file_path):
    with open(log_file_path) as f:
        for line in f:
            yield line.strip()

def log_analyzer(log_file_path, keyword):
    log_reader = log_file_reader(log_file_path)
    count = 0
    for line in log_reader:
        if keyword in line:
            count += 1
    return count

log_file_path = 'logs.txt'
keyword = 'error'
error_count = log_analyzer(log_file_path, keyword)
print(f'The number of error logs is: {error_count}')

本文转载于 WX 公众号:不背锅运维(喜爱的盆友关注咱们):https://mp.weixin.qq.com/s/g9A4rMKscHt8gKJq34sKQw

正文完
 0