Python

时间:2016-09-18 19:34:43

标签: python

使用一个行循环,甚至嵌套循环总是Python中的一个好习惯吗?我看到很多人只是喜欢和#34; one-liners",但对我来说,他们有时难以阅读,特别是如果我们谈论嵌套循环。

此外,我到目前为止看到的大多数嵌套循环都超过了每行推荐的79个字符。

所以我想知道" one-liners"提供紧凑的任何额外的东西?他们可能会使用更少的内存吗?

4 个答案:

答案 0 :(得分:5)

是的,它们可能更容易更快,因为可以在C中运行更多代码(在显式循环中,所有直接步骤必须可用于解释器,在一线列表理解中它不必)。还有.append方法调用,方法查找等的开销。在列表理解中,所有这些都被避免了:

import timeit


def f1():
    result = []
    for x in range(100):
        for y in range(100):
            result.append(x * y)
    return result


def f2():
    return [x * y for y in range(100) for x in range(100)]


print('loop: ', timeit.timeit(f1, number=1000))
print('oneliner:', timeit.timeit(f2, number=1000))

结果(Python 3):

loop:  1.2545137699926272
oneliner: 0.6745600730064325

答案 1 :(得分:1)

取决于单行,有些可以更高效,更易读。

以列表理解为例。假设您想要从1到10中取所有数字并输出其产品列表乘以2.

输入:[1,2,3,...,9,10]
输出:[2,4,6,...,18,20]

您可以在for循环中执行此操作:

output = []
for i in range(1, 11):
    output.append(i*2)

或者你可以使用列表理解:

[i*2 for i in range(1,11)]

您会看到列表理解速度更快,而且非常易读。

对于词典理解,集合理解和生成器表达式也可以这样说。此外,只要可以理解,map()filter()的使用就会受到高度鼓励。

答案 2 :(得分:0)

For discussion... they all do the same.

'a' a list comprehension... the smoking one-liner... 'b' same thing, but you can provide annotation within a list comprehension... it is still technically a one-liner 'c' the conventional approach. If speed is a concern, I am less worried about the speed unless, I perform the same task day in day out and it takes a really long time to perform. Comparing speed when you are talking micro or nanoseconds may be of academic interest, but it will not impact the vast majority of users. I always vote for clarity of expression over compactness of code.

a = [i**2 for i in range(20) if i > 5 and i < 10]

b = [i**2               # do this  
     for i in range(20) # using these  
     if (i > 5) and     # where this and  
        (i < 10)        # this is good  
     ]  

c = []  
for i in range(20):  
    if (i > 5) and (i < 10):  
        c.append(i**2)  

EDIT The example given of producing the product of a range of numbers, is a good indicator, that the oneliner need not be the issue, but the method used to obtain the result. I will illustrate with determining the product using only 10 values... try it with 100 if you like. I will do it in full format, but could reduce everything to a oneliner if need (import excluded).

>>> import numpy as np
>>> a = np.arange(10)
>>> b = np.arange(10).reshape(10,1)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b
array([[0],
       [1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])
>>> a*b
array([[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18],
       [ 0,  3,  6,  9, 12, 15, 18, 21, 24, 27],
       [ 0,  4,  8, 12, 16, 20, 24, 28, 32, 36],
       [ 0,  5, 10, 15, 20, 25, 30, 35, 40, 45],
       [ 0,  6, 12, 18, 24, 30, 36, 42, 48, 54],
       [ 0,  7, 14, 21, 28, 35, 42, 49, 56, 63],
       [ 0,  8, 16, 24, 32, 40, 48, 56, 64, 72],
       [ 0,  9, 18, 27, 36, 45, 54, 63, 72, 81]])

or as a one-liner

>>> out = np.arange(10) * np.arange(10).reshape(10,1)

and of course there are built-in functions to do this without the full expression I have shown.

The point being made, speed isn't everything. Clarity of code AND choosing the right tools to do the job should be considered first.

答案 3 :(得分:-1)

是。这是一种很好的做法。

通常有经验的程序员在单行循环中使用匿名函数(参见lambda:http://www.secnetix.de/olli/Python/lambda_functions.hawk),它会提供更好的性能。