简体   繁体   English

具有多个任务的列表理解

[英]list comprehension with multiple assignments

I presently have this code for factoring large numbers: 我目前有这段代码可以分解大量数字:

def f1(n):
    return [[i, n//i] for i in range(1 , int(n**0.5) + 1) if n % i == 0]

It's the fastest version I've seen so far (If there's a faster way I'd love to know about that as well), but I'd like a single list of all the factors with no nesting (so I want something like: [factor 1, factor 2, factor 3,..., factor n-3, factor n-2, factor n-1, factor n] and so on. The order isn't really important. 这是到目前为止我所见过的最快的版本(如果我也想知道一种更快的方法),但是我想要一个没有嵌套的所有因素的清单(所以我想要类似的东西: [factor 1, factor 2, factor 3,..., factor n-3, factor n-2, factor n-1, factor n]等等,顺序并不是很重要。

As such I was wondering if there was a way to ascribe multiple assignments via a list comprehension. 因此,我想知道是否有一种方法可以通过列表理解来分配多个任务。

ie

def f1(n):
    return [i, n//i for i in range(1 , int(n**0.5) + 1) if n % i == 0]

That way I don't have a nested list. 这样,我就没有嵌套列表。 It would be faster and speed is of the essence. 它将更快并且速度至关重要。

I looked in the documentation and I couldn't find a single example of multiple assignments. 我查看了文档,找不到多个分配的单个示例。

Use itertools.chain : 使用itertools.chain

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))

If you don't need a list remove the list call on chain and just iterate over the returned chain object. 如果不需要列表,请删除链上的列表调用,然后迭代返回的链对象。

If optimization is important you should use extend and xrange: 如果优化很重要,则应使用extend和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

List comprehensions are great, but sometimes they're not best the solution, depending on requirements for readability and speed. 列表理解能力很好,但有时并不是最佳解决方案,具体取决于可读性和速度要求。 Sometimes, just writing out the implied for loop (and if statement) is more readable and quicker. 有时,仅写出隐含的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

For small numbers, the above function is quicker than the list comprehension. 对于较小的数字,上述功能比列表理解要快。 At larger numbers (1,000,000 and bigger), the function and list comprehension are equal in terms of speed. 在较大的数字(1,000,000或更大)上,函数和列表推导的速度相等。

For a slight speed increase you can also cache the append method of the list, though this makes the function slightly less readable. 为了稍微提高速度,您还可以缓存列表的append方法,尽管这会使函数的可读性稍差。

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

Speed comparison: 速度比较:

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

You can achieve the desired result using sum() . 您可以使用sum()获得所需的结果。 For example: 例如:

>>> sum([[1,6],[2,3]],[])
[1, 6, 2, 3]

We can define the answer in terms of your existing code: 我们可以根据您现有的代码来定义答案:

def f2(n):
    return sum(f1(n), [])

However, be careful that your code returns the square root twice when n is a perfect square: 但是,请注意,当n是理想平方时,您的代码将两次返回平方根:

>>> f1(9)
[[1, 9], [3, 3]]
>>> f2(9)
[1, 9, 3, 3]

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

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