![](/img/trans.png)
[英]What is the most pythonic way to apply a function on and return multiple columns?
[英]What is the most pythonic way to apply function to some items of a list?
让我们使用这段代码打印列表的所有正面 integer :
l = [1, -1, 1, 0, 2]
for i in l:
if i > 0:
print(i)
我可以通过列表理解来做到这一点,但我想这对创建一个新的无用列表有不利之处:
[print(i) for i in l if i > 0]
所以我的问题是:有没有更 Pythonic 的方式来写这个?
普通的 for 循环是完全 Pythonic 的。 您想遍历列表的元素 select 大于零的元素,然后打印它们,这正是它所做的 - 不多也不少。
列表理解不是 Pythonic ,主要是因为您给出的原因:它创建了一个新的无用列表。 即使您打算使用 list ,使用列表推导来处理副作用仍然是不好的做法。
将 function 应用于元素列表的某个子集的最 Pythonic 方法是使用for
循环,就像您已经拥有的一样。
在那个for
循环中,在将任何值分配给i
之前,有一个参数用于过滤列表; 这是否构成改进通常是一个见仁见智的问题,将取决于具体情况。
for i in filter(lambda x: x > 0, l):
print(i)
在这种情况下,我认为情况更糟。 但有时你手头有一个谓词,过滤在语法上可以更轻松。 相比
for i in some_list_of_strings:
if i.isdigit():
print(i)
和
for i in filter(str.isdigit, some_list_of_strings):
print(i)
我想理论上你可以设法使用生成器理解以避免在 memory 中创建一个大列表:
for _ in (print(i) for i in l if i > 0): pass
(也许还使用一些 function 来消耗来自生成器的值,因此任何循环都隐藏在该函数内)。
但是,这不仅比显式for
循环可读性差,而且纯for
循环也更快。
import time
l = [1, -1, 1, 0, 2]
# we don't really want lots of output for this timing test
def dont_really_print(i):
return i
t1 = time.time()
for x in range(1000000):
for i in l:
if i > 0:
dont_really_print(i)
t2 = time.time()
for x in range(1000000):
for _ in (dont_really_print(i) for i in l if i > 0):
pass
t3 = time.time()
print(f"generator comprehension {t3 - t2:.3f} "
f"explicit loop {t2 - t1:.3f}")
给出:
generator comprehension 0.629 explicit loop 0.423
通常,无论是 Python 还是其他任何语言,您要做的事情都称为“地图”。
打印是一个奇怪的 function 到 map,所以这里是另一个 function 用于更好的演示目的。
def add_one(num):
return num + 1
foo = [1, 2, 3, 4]
new_list = map(add_one, foo)
print(list(new_list))
您通常可以并行使用 map,有时是异步的,并且大量并行处理范例(包括 Python 的多处理)使用 map 作为使用多核实现 ZC1C425268E68385D1AB5074C14 的基本操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.