2017-03-17 24 views
3

我有一個CSV數據文件的目錄,我在列表理解語句中使用pandas.read_csv()將它們全部加載到一行中。如何在列表理解中使用print()以及其他操作?

import glob 
import pandas as pd 
file_list = glob.glob('../data/') 
df_list = [pd.read_csv(f) for f in file_list] 
df = pd.concat(df_list, ignore_index=True) 

現在我想在加載數據文件,每次打印的文件路徑,但我不能找到一種方法,使用列表理解多條語句。例如,像[pd.read_csv(f); print(f) for f in file_list]這樣的東西將導致SyntaxError

我可以得到的最接近的東西是讓print()在if語句中返回None,打印後它的工作方式與pass類似。

df_list = [pd.read_csv(f) for f in file_list if print(f) is None] 

有沒有適當的方法做到這一點?我喜歡列表理解的簡潔性,但似乎並沒有允許多個語句。

回答

1

如果你想有一個列表理解(理解的,因爲在for循環速度的提高) ,你可以稍微修改您的解決方案,因爲None是falsy:

df_list = [pd.read_csv(f) for f in file_list if not print(f)] 

或者使該做的工作的函數:

def read_and_print(f): 
    print(f) 
    return pd.read_csv(f) 

df_list = [read_and_print(f) for f in file_list] 

但是,這些方法違反了Python通常遵循的命令查詢分離原則,因爲該函數同時具有副作用和return值。儘管如此,我認爲這些都是非常實用的,特別是如果您現在要print()查看數據,但稍後您計劃刪除print()調用。

2

列表理解不是爲此設計的。相反,只是爲了填充循環遍歷某些迭代的列表,並且(可選)滿足條件。 Python喜歡強調通過代碼行的可讀性。

正確的方法做你想要的是不使用列表理解可言,而是一個for循環:

for f in file_list: 
    print(f) 
    df_list.append(pd.read_csv(f)) 
0

如前所述,您通常不應該在列表理解中使用帶副作用的函數。不過,我明白用於調試目的這樣的事情可能會有用。

的一種方式,類似於您if條件,是使用or,利用的事實print函數返回None,從而評估並返回第二個操作:

df_list = [print(f) or pd.read_csv(f) for f in file_list] 

但是,這可能是難以理解,意圖不是很明確。或者,你可以定義一個peek功能,打印和返回參數和使用,在修真:

def peek(x, *args, **kwargs): 
    print(x, *args, **kwargs) 
    return x 

df_list = [pd.read_csv(peek(f)) for f in file_list] 

你也可以讓這個更通用,傳遞給應用功能(print在這種情況下)作爲另一參數設置爲peek函數,或者首先檢查某個全局變量debug_enabled是否實際設置爲True

相關問題