繁体   English   中英

单列表迭代与多列表理解

[英]Single list iteration vs multiple list comprehensions

我有一个数据列表,我需要将其中的某些元素复制到几个不同的列表中。 进行列表的单次迭代或执行多个列表理解会更好吗?

例如

def split_data(data):
    a = []
    b = []
    c = []
    for d in data:
        if d[0]   >   1 : a.append(d)
        if d[1]   == 'b': b.append(d)
        if len(d) ==  3 : c.append(d)

    return a, b, c

def split_data(data):
    a = [d for d in data if d[0]   >   1 ]
    b = [d for d in data if d[1]   == 'b']
    c = [d for d in data if len(d) ==  3 ]

    return a, b, c

我知道执行列表操作的更多Python方式是列表理解,但是在这种情况下是这种情况吗?

在第一个示例代码中,它只需要使用多个if语句对数据进行一次迭代,而后面的代码则需要对数据进行3次遍历。 我相信列表理解将在大多数时间内以与数据相等的迭代次数获胜。

对于像您的示例这样的简单操作,我宁愿使用列表理解方法,当操作变得更加复杂时,出于代码可读性的考虑,也许其他方法会更好。

关于2函数的一些基准测试可以告诉您更多信息。 基于我使用一些虚拟数据集对这两个函数的快速基准测试,如下所示。 此运行时可能并不总是正确,取决于数据集

# without list comprehension
>>> timeit.timeit('__main__.split_data([("a","b")] * 1000000)', 'import __main__', number=1)
0.43826036048574224

# with list comprehension
>>> timeit.timeit('__main__.split_data([("a","b")] * 1000000)', 'import __main__', number=1)
0.31136326966964134

我会说这取决于。 如果您的d是一个列表且相对较小,则可以进行列表理解。 但是,如果您的d较大(提示%timeit是您的朋友),则您的第一个选择只会对其进行一次迭代,因此可能会更有效。

另请注意,您的第一个版本将适用于所有生成器,而第二个版本将不适用于消耗物品的生成器。 您甚至可以自己提供一个生成器来链接它,即使用yield a, b, c而不是return

如果您想使用更多pythonic,我们可以咨询zen python。

Explicit is better than implicit.

Sparse is better than dense.

Readability counts.

尽管两者都是可读的,但我想说您的第一个示例更具可读性。 如果您的data具有更大的维度,并且需要更多的嵌套嵌套循环,那么第一个示例将更清楚地说明如果涉及更多逻辑,则如何处理每个嵌套元素。

尽管Skycc的回答确实显示了列表理解的结果稍快一些,但理想情况下,您应该首先阅读易读性,然后再进行优化,除非您真的需要从列表理解中获得一点提速。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM