你可以让这一点通过使用if
表达短:
def f(objects):
list_type = "string_x"
other = "string_y"
hold = []
for x in objects:
hold.append((list_type if isinstance(x[1], list) else other, x[1]))
return hold
然后很容易变成理解,它更短,可能更易读,更快一些:*
def f(objects):
list_type = "string_x"
other = "string_y"
return [(list_type if isinstance(x[1], list) else other, x[1])
for x in objects]
真的,我不知道那些局部变量是使事情更清楚:**
def f(objects):
return [("string_x" if isinstance(x[1], list) else "string_y", x[1])
for x in objects]
同时,如果你要与返回的列表做的唯一事情就是迭代(例如,因为这只是转换链中的一个),你根本不应该返回一个列表。无论是yield
每个值,返回genexpr而不是listcomp,或者(如果你有Python的3.3+)获得两全其美:
def f(objects):
yield from (("string_x" if isinstance(x[1], list) else "string_y", x[1])
for x in objects)
*您还在做同样的循环,所以你有完全相同的算法复杂性。然而,循环和列表追加都是通过采用一些快捷方式的自定义字节码来实现的,这使得每次迭代更加高效。 (“自定义字节码”的细节当然具体到CPython的和其他的字节码兼容的实现比如PyPy,但在一般情况下,任何实现至少可能承担list解析快捷方式。)
**这最后很可能稍微快一点,因为它将常量加载到堆栈而不是本地变量。再次,它可能也有稍差的缓存局部性。如果真的很重要,请测试并看看。
灿你举了一个你作为'objects'传递的例子吗? – brandonscript
“高效”是指“快速”还是“可读”或其他不同?是什么让你觉得它效率不高? – abarnert
无论你如何去做,地图,列表理解或其他,它必须是*某种排序*循环 – yuvi