我有一个CSV数据文件目录,我在列表推导语句中使用pandas.read_csv()
将所有这些文件加载到一行中。
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
,if语句在打印后就像pass
一样。
df_list = [pd.read_csv(f) for f in file_list if print(f) is None]
有没有正确的方法呢?我喜欢列表理解的简洁性,但它似乎不允许多个语句。
答案 0 :(得分:2)
列表理解不是为此而设计的。相反,仅用于填充循环遍历某个iterable的列表,以及(可选地)满足条件。 Python喜欢强调代码行的可读性。
做你想做的事的正确方法是根本不使用列表理解,而是使用for循环:
for f in file_list:
print(f)
df_list.append(pd.read_csv(f))
答案 1 :(得分:2)
如果你想要一个列表理解(考虑到for
循环的速度改进可以理解),你可以稍微修改你的解决方案,因为None
是假的:
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 :(得分:1)
如前所述,通常不应在列表推导中使用带副作用的函数。但是,我很欣赏用于调试目的这样的东西可能会有用。
与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
。