为什么我不能拆分这个python列表?

2024-07-05 15:18:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些代码来解析apache日志文件(start_search,和end_search是apache日志中的日期字符串格式):

with open("/var/log/apache2/access.log",'r') as log:
    from itertools import takewhile, dropwhile
    s_log = dropwhile(lambda L: start_search not in L, log)
    e_log = takewhile(lambda L: end_search not in L, s_log)
    query = [line for line in e_log if re.search(r'GET /(.+veggies|.+fruits)',line)]

    import csv
    query_dict = csv.DictReader(query,fieldnames=('ip','na-1','na-2','time', 'zone', 'url', 'refer', 'client'),quotechar='"',delimiter=" ")

    import re
    veggies = [ x for x in query_dict if re.search('veggies',x['url']) ]
    fruits = [ x for x in query_dict if re.search('fruits',x['url']) ]

第二个列表生成器始终为空;也就是说,如果切换最后两行的顺序:

    fruits = [ x for x in query_dict if re.search('fruits',x['url']) ]
    veggies = [ x for x in query_dict if re.search('veggies',x['url']) ]

第二个列表总是空的。你知道吗

为什么?(如何填充fruitsveggies列表?)你知道吗


Tags: inimportrelogurl列表forsearch
1条回答
网友
1楼 · 发布于 2024-07-05 15:18:47

您只能循环遍历迭代器一次query_dict是一个迭代器,它曾经扫描过veggies,但不能再次遍历以搜索fruits。你知道吗

这里不要使用列表理解。在query_dict上循环一次,检查每个条目的veggiesfruits

veggies = []
fruits = []

for x in query_dict:
    if re.search('veggies',x['url']):
         veggies.append(x)
    if re.search('fruits',x['url']):
         fruits.append(x)

备选方案是:

  • fruits列表重新创建csv.DictReader()对象:

    query_dict = csv.DictReader(query,fieldnames=('ip','na-1','na-2','time', 'zone', 'url', 'refer', 'client'),quotechar='"',delimiter=" ")
    veggies = [ x for x in query_dict if re.search('veggies',x['url']) ]
    query_dict = csv.DictReader(query,fieldnames=('ip','na-1','na-2','time', 'zone', 'url', 'refer', 'client'),quotechar='"',delimiter=" ")
    fruits = [ x for x in query_dict if re.search('fruits',x['url']) ]
    

    这会产生双重效果;您会在整个数据集上循环两次。

  • 使用^{}来“克隆”迭代器:

    from itertools import tee
    veggies_query_dict, fruits_query_dict = tee(query_dict)
    veggies = [ x for x in veggies_query_dict if re.search('veggies',x['url']) ]
    fruits = [ x for x in fruits_query_dict if re.search('fruits',x['url']) ]
    

    这最终会将所有query_dict缓存在tee缓冲区中,需要两倍于同一任务的内存,直到fruits再次清空缓冲区。

相关问题 更多 >