列表理解与多项任务
list comprehension with multiple assignments
我现在有这个用于分解大数的代码:
def f1(n):
return [[i, n//i] for i in range(1 , int(n**0.5) + 1) if n % i == 0]
这是迄今为止我见过的最快的版本(如果有更快的方法我也很想知道),但我想要一个没有嵌套的所有因素的列表(所以我想要类似的东西:[factor 1, factor 2, factor 3,..., factor n-3, factor n-2, factor n-1, factor n]
等等。顺序并不重要。
因此我想知道是否有一种方法可以通过列表理解来归因于多个分配。
即
def f1(n):
return [i, n//i for i in range(1 , int(n**0.5) + 1) if n % i == 0]
这样我就没有嵌套列表了。它会更快,速度至关重要。
我查看了文档,但找不到多个分配的单个示例。
您可以使用 sum() 获得所需的结果。例如:
>>> sum([[1,6],[2,3]],[])
[1, 6, 2, 3]
我们可以根据您现有的代码定义答案:
def f2(n):
return sum(f1(n), [])
但是,请注意当 n
是一个完全平方时,您的代码 returns 平方根两次:
>>> f1(9)
[[1, 9], [3, 3]]
>>> f2(9)
[1, 9, 3, 3]
from itertools import chain
def f1(n):
return list(chain.from_iterable([i, n//i] for i in xrange(1 , int(n**0.5) + 1) if not n % i))
如果您不需要列表,请删除链上的列表调用,然后迭代返回的链对象。
如果优化很重要,您应该使用扩展和 xrange:
def f1(n):
l = []
for i in xrange(1, int(n**0.5)+1):
if not n % i:
l.extend((i,n//i))
return l
列表推导式很好,但有时它们并不是最佳解决方案,具体取决于对可读性和速度的要求。有时,只写出隐含的 for 循环(和 if 语句)更具可读性和更快。
def factors(n):
l = []
for i in range(1, int(n**0.5)+1):
if n % i == 0:
l.append(i)
l.append(n//i)
return l
对于小数字,上述函数比列表理解更快。在更大的数字(1,000,000 和更大)下,函数和列表理解在速度方面是相等的。
为了稍微提高速度,您还可以缓存列表的附加方法,尽管这会使函数的可读性稍差。
def factors(n):
l = []
append = l.append
for i in range(1, int(n**0.5)+1):
if n % i == 0:
append(i)
append(n//i)
return l
速度比较:
In [86]: %timeit factors_list_comprehension(1000)
100000 loops, best of 3: 7.57 µs per loop
In [87]: %timeit factors_function(1000)
100000 loops, best of 3: 6.24 µs per loop
In [88]: %timeit factors_optimised_function(1000)
100000 loops, best of 3: 5.81 µs per loop
In [89]: %timeit factors_list_comprehension(1000000)
10000 loops, best of 3: 111 µs per loop
In [90]: %timeit factors_function(1000000)
10000 loops, best of 3: 108 µs per loop
In [91]: %timeit factors_optimised_function(1000000)
10000 loops, best of 3: 106 µs per loop
我现在有这个用于分解大数的代码:
def f1(n):
return [[i, n//i] for i in range(1 , int(n**0.5) + 1) if n % i == 0]
这是迄今为止我见过的最快的版本(如果有更快的方法我也很想知道),但我想要一个没有嵌套的所有因素的列表(所以我想要类似的东西:[factor 1, factor 2, factor 3,..., factor n-3, factor n-2, factor n-1, factor n]
等等。顺序并不重要。
因此我想知道是否有一种方法可以通过列表理解来归因于多个分配。
即
def f1(n):
return [i, n//i for i in range(1 , int(n**0.5) + 1) if n % i == 0]
这样我就没有嵌套列表了。它会更快,速度至关重要。
我查看了文档,但找不到多个分配的单个示例。
您可以使用 sum() 获得所需的结果。例如:
>>> sum([[1,6],[2,3]],[])
[1, 6, 2, 3]
我们可以根据您现有的代码定义答案:
def f2(n):
return sum(f1(n), [])
但是,请注意当 n
是一个完全平方时,您的代码 returns 平方根两次:
>>> f1(9)
[[1, 9], [3, 3]]
>>> f2(9)
[1, 9, 3, 3]
from itertools import chain
def f1(n):
return list(chain.from_iterable([i, n//i] for i in xrange(1 , int(n**0.5) + 1) if not n % i))
如果您不需要列表,请删除链上的列表调用,然后迭代返回的链对象。
如果优化很重要,您应该使用扩展和 xrange:
def f1(n):
l = []
for i in xrange(1, int(n**0.5)+1):
if not n % i:
l.extend((i,n//i))
return l
列表推导式很好,但有时它们并不是最佳解决方案,具体取决于对可读性和速度的要求。有时,只写出隐含的 for 循环(和 if 语句)更具可读性和更快。
def factors(n):
l = []
for i in range(1, int(n**0.5)+1):
if n % i == 0:
l.append(i)
l.append(n//i)
return l
对于小数字,上述函数比列表理解更快。在更大的数字(1,000,000 和更大)下,函数和列表理解在速度方面是相等的。
为了稍微提高速度,您还可以缓存列表的附加方法,尽管这会使函数的可读性稍差。
def factors(n):
l = []
append = l.append
for i in range(1, int(n**0.5)+1):
if n % i == 0:
append(i)
append(n//i)
return l
速度比较:
In [86]: %timeit factors_list_comprehension(1000)
100000 loops, best of 3: 7.57 µs per loop
In [87]: %timeit factors_function(1000)
100000 loops, best of 3: 6.24 µs per loop
In [88]: %timeit factors_optimised_function(1000)
100000 loops, best of 3: 5.81 µs per loop
In [89]: %timeit factors_list_comprehension(1000000)
10000 loops, best of 3: 111 µs per loop
In [90]: %timeit factors_function(1000000)
10000 loops, best of 3: 108 µs per loop
In [91]: %timeit factors_optimised_function(1000000)
10000 loops, best of 3: 106 µs per loop