2013-07-24 42 views
1

當調查我的其他問題時,我遇到了一個非常奇怪的行爲。將`filter object`投射到`list`清除其內容

運行代碼:

def test(prefix, custom_meta_files = []): 
    postfix = 'tgz' 
    if prefix[-1] != '.': 
    postfix = '.tgz' 

    archive = tarfile.open(prefix+postfix, "w:gz") 
    files = filter(lambda path: path.startswith(prefix), os.listdir()) 
    print('files: {0}'.format(list(files))) 
    print('files: {0}'.format(list(files))) 


files: ['ga_run.seq_niche.N30.1.bt0_5K.params', 'ga_run.seq_niche.N30.1.bt0_5K.stats', 'ga_run.seq_niche.N30.1.bt0_5K.tgz'] 
files: [] 

好像鑄造filter objectlist將其清除。爲什麼這樣,是否是理想的?

回答

0

當你這樣做:

list(files) 

你有效地消耗你寫list(files)的通過filter創建一個列表(它不是一個「演員」的方式)返回發生器,使得第二次發電機已經完成。這應該可以解決它,並且它也是存儲在變量重複的結果是一個好主意 - 它避免了重新計算值:

lst = list(files) 
print('files: {0}'.format(lst)) 
print('files: {0}'.format(lst)) 
+0

所以我說得對。即使本質上與我的相同,我也會接受你的答案,但是我不想因爲我在1分鐘前寫了這兩天而等待兩天。我也認爲我可以保存並重用。起初,我認爲過濾器會返回一個更像'list'的持久對象,而不是一個生成器。感謝您的確認! – luk32

1

嗯...我可能會變成是愚蠢的。但我又開始閱讀文檔,我想我找到了原因。我把它作爲一個自我回答發佈,因爲我認爲這個問題是有效的,不值得去除。如果函數不是None並且(item中item可以迭代,如果item)如果filter(函數,iterable)等價於生成器表達式(item中item的可迭代if(item))if功能是無「。

所以,如果它作爲一個發電機的可能鑄造它迭代發電機,並有效地「清空」它。

不過,如果任何python專家能指出,如果這是正確的思維方式,我將不勝感激。

+0

是的,'過濾器'返回一個生成器並將該生成器轉換爲列表使用它。如果你需要列表形式,最好的辦法是把它轉換成列表並將該列表分配給一個變量。 – llb