簡體   English   中英

Pythonic方法處理多個for循環使用不同的過濾器對同一個列表?

[英]Pythonic way to process multiple for loops with different filters against the same list?

這是我正在編寫的一個程序,它將創建一個對文件目錄進行分類的csv:

matches = []
for root, dirnames, filenames in os.walk(directory):
    for filename in fnmatch.filter(filenames, '*[A-Z]*'):
        matches.append([os.path.join(root, filename), "No Capital Letters!"])

    test = re.compile(".*\.(py|php)", re.IGNORECASE)
    for filename in filter(test.search, filenames):
        matches.append([os.path.join(root, filename), "Invalid File type!"])

基本上,用戶選擇一個文件夾,程序表示問題文件,可以是幾種類型(這里只列出兩種:沒有大寫字母的文件,沒有php或python文件)。 可能會有五六個案例。

雖然這有效,但我想重構。 是否有可能做類似的事情

for filename in itertools.izip(fnmatch.filter(filenames, '*[A-Z]*'), filter(test.search, filenames), ...):
    matches.append([os.path.join(root, filename), "Violation")

能夠跟蹤哪些原始解壓縮列表導致“違規”?

一個更簡單的解決方案可能是先迭代文件,然后逐個應用檢查:

reTest = re.compile(".*\.(py|php)", re.IGNORECASE)
for root, dirnames, filenames in os.walk(directory):
    for filename in filenames:
        error = None
        if fnmatch.fnmatch(filename, '*[A-Z]*'):
            error = 'No capital letters!'
        elif reTest.search(filename):
            error = 'Invalid file type!'

        if error:
            matches.append([os.path.join(root, filename), error])

這不僅會使邏輯變得更簡單,因為您只需要檢查單個文件(而不必每次都計算出如何在一系列文件名上調用check方法),它也只會迭代一次。文件名列表。

此外,它還將避免為單個文件名生成多個匹配項; 它最多只添加一個錯誤(第一個)。 如果你不想這樣,你可以將error改為列表並在你的支票中附加到它 - 當然你想要將elif改為if然后評估所有支票。

我建議你看看這些幻燈片

David Beazley給出了使用yield來處理日志文件的示例。

編輯:以下是pdf中的兩個示例,一個沒有生成器:

wwwlog = open("access-log")
total = 0
for line in wwwlog:
  bytestr = line.rsplit(None,1)[1]
   if bytestr != '-':
     total += int(bytestr)
 print "Total", total

並使用生成器(可以使用帶有yield的函數來獲得更復雜的示例)

wwwlog = open("access-log")
bytecolumn = (line.rsplit(None,1)[1] for line in wwwlog)
bytes = (int(x) for x in bytecolumn if x != '-')
print "Total", sum(bytes)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM