我如何 运行 在 python 中的另一个列表中使用一个列表的模条件

How do I run a modulo conditional using one list on another list in python

我只使用 python 大约 2 周,需要一些帮助。我正在尝试在两个不同大小的列表之间使用 mod (%) 函数。

n = 23 #user input, starting point for the code
listp = [2, 3, 5, 7, 11, 13]
listr = list(range((n-1)**2, n**2+1, 2))
listb = list(listr)  #I need to remove items from listr but if i do, it 
                     #crashes so I decided to copy it to listb in order to manipulate it

for k in listr:
    for i in listp[1:]:
        if k%i == 0:
            if k in listb:
                listb.remove(k)

这行得通,但速度很慢,我想直接操作 listr,我可以单独操作:

listr = [k for k in listr if i%listp[1] !=0]
listr = [k for k in listr if i%listp[2] !=0] 

最重要的是,我想在 listr 中的每个 k 元素上使用 % 函数,使用 listp 中的每个 i 元素,并且只保留 listr 中 !=0 的那些元素;我试过使用 numpy 和数组,但这也无济于事

您可以从找到 any 这样的值的那一刻起停止。所以替换:

for k in listr:
    <b>for i in listp[1:]:
        if k%i == 0:</b>
            if k in listb:
                listb.remove(k)

有:

for k in listr:
    <b>if any(k%i == 0 for i in listp[1:]):</b>
        listb.remove(k)

这已经产生了一些加速。但是 list.remove 很慢,它在 O(n) 中有效。所以现在我们可以把它变成列表理解:

listr = [k for k in listr <b>if not any(k%i == 0 for i in listp[1:])</b>]

因此,如果不满足这样的取模条件,我们将数字添加到新的 listr 列表中。一个not any(p(x) for x in X)可以改写成all(not p(x) for x in X),所以我们可以在这里套用:

listr = [k for k in listr if <b>all(k%i != 0</b> for i in listp[1:])]

此外,我们还可以通过制作列表来节省一些周期listp1:

<b>listp1 = listp[1:]</b>
listr = [k for k in listr if all(k%i != 0 for i in <b>listp1</b>)]

从现在开始我们只构造一个新列表一次。最后我们可以删除 != 0 因为整数的真实性是 True 当且仅当值不等于零时:

listp1 = listp[1:]
listr = [k for k in listr if all(k%i for i in listp1)]

请注意,有比 Eratosthenes 筛选法更快的方法。

为了更快的操作,您可以尝试使用 pandas, it uses numpy under the hood and "pushes the work down to C level". Look at arange

然后创建一个函数来完成你想要的工作,然后 apply 它到你的熊猫数据结构的所有条目并捕获它:类似于

最终_list = pandas_struct.apply(函数)

您可以玩的一些示例如下: 多快可以接受?

import numpy as np
import pandas as pd

n=23
first = np.array([2, 3, 5, 7, 11, 13])
second = np.arange((n-1)**2, n**2+1, 2)
pand_second=pd.Series(second)

def modme(num,div):
    if num % div  == 0:
        return num,'mod ok by',div

[9]: pand_second.apply(modme, args=(3,))
Out[9]: 
0                    None
1     (486, mod ok by, 3)
2                    None
3                    None
4     (492, mod ok by, 3)
5                    None
6                    None
7     (498, mod ok by, 3)
8                    None
9                    None
10    (504, mod ok by, 3)
11                   None
12                   None
13    (510, mod ok by, 3)
14                   None
15                   None
16    (516, mod ok by, 3)
17                   None
18                   None
19    (522, mod ok by, 3)
20                   None
21                   None
22    (528, mod ok by, 3)
dtype: object


%timeit pand_second.apply(modme, args=(3,))
81.3 µs ± 201 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

或者根本不使用 pandas:):

import numpy as np

n=23
first = np.array([2, 3, 5, 7, 11, 13])
second = np.arange((n-1)**2, n**2+1, 2)

In [11]: [ second[ second % x == 0 ] for x in first ]
Out[11]: 
[array([484, 486, 488, 490, 492, 494, 496, 498, 500, 502, 504, 506, 508,
        510, 512, 514, 516, 518, 520, 522, 524, 526, 528]),
 array([486, 492, 498, 504, 510, 516, 522, 528]),
 array([490, 500, 510, 520]),
 array([490, 504, 518]),
 array([484, 506, 528]),
 array([494, 520])]


%timeit [ second[ second % x == 0 ] for x in first ]
15.6 µs ± 25.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)