如何使用python

时间:2017-11-17 14:44:52

标签: python numpy iteration conditional modulo

我只使用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和一个数组,但这并没有帮助

2 个答案:

答案 0 :(得分:3)

您可以从找到any此值的那一刻开始停止。所以替换:

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

使用:

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

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

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

因此,如果没有这样的模数条件,我们将数字添加到新的listr列表中。 not any(p(x) for x in X)可以重写为all(not p(x) for x in X),因此我们可以在此处应用:

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

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

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

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

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

请注意,有比 Sieve of Eratosthenes 更快的方法。

答案 1 :(得分:-1)

为了更快的操作,你可以尝试使用pandas,它使用numpy并“将工作推向C级”。看arange

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

final _list = pandas_struct.apply(function)

您可以使用以下示例进行操作: 有多快可以接受?

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)