如何在列表理解中使用print()和其他操作?

时间:2017-03-17 10:16:39

标签: python list-comprehension

我有一个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]

有没有正确的方法呢?我喜欢列表理解的简洁性,但它似乎不允许多个语句。

3 个答案:

答案 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