Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Numpy 比较列表和提取某些数据的最佳实践_Numpy_Diff_Python 3.7 - Fatal编程技术网

Numpy 比较列表和提取某些数据的最佳实践

Numpy 比较列表和提取某些数据的最佳实践,numpy,diff,python-3.7,Numpy,Diff,Python 3.7,我有一个旧的电子邮件列表,应该更新为新的电子邮件列表 我需要最有效的方法来比较它们并选择从旧列表中删除的电子邮件 电子邮件列表存储在数据库中,因此我可以获得电子邮件ID(电子邮件是唯一的) 我使用的代码: old_ids_list = [1, 2, 3] new_ids_list = [1, 2] old_emails_list = ['toto@gmail.com', 'lolo@gmail.com', 'momo@gmail.com'] new_emails_list = ['toto@gm

我有一个旧的电子邮件列表,应该更新为新的电子邮件列表

我需要最有效的方法来比较它们并选择从旧列表中删除的电子邮件

电子邮件列表存储在数据库中,因此我可以获得电子邮件ID(电子邮件是唯一的)

我使用的代码:

old_ids_list = [1, 2, 3]
new_ids_list = [1, 2]
old_emails_list = ['toto@gmail.com', 'lolo@gmail.com', 'momo@gmail.com']
new_emails_list = ['toto@gmail.com', 'lolo@gmail.com',]

if len(old_ids_list) == len(new_ids_list) & len(set(old_ids_list) & set(new_ids_list)) == len(old_ids_list):
    pass
else:
    deleted = numpy.setdiff1d(old_emails_list, new_emails_list, assume_unique=False)

这是一种好的做法吗?或者最好对循环使用
?为什么?你可以使用列表理解。正如你所说,电子邮件本身是独一无二的,我不确定你想用ID做什么,我们不需要转换成集合(如果我搞错了,请纠正我)

imho这种方法的优点是可读性好,不需要外部包

编辑
要检查新列表是否与旧列表不同,有两个szenarios:
a) 如果已知新列表是旧列表的子列表,只需检查上文计算的
已删除
中是否有任何元素。

b) 如果新列表中可能有新的电子邮件,请检查
已删除的
是否包含任何电子邮件,如果没有,请另外检查
len(新电子邮件列表)==len(旧电子邮件列表)

您可以使用列表理解。正如你所说,电子邮件本身是独一无二的,我不确定你想用ID做什么,我们不需要转换成集合(如果我搞错了,请纠正我)

imho这种方法的优点是可读性好,不需要外部包

编辑
要检查新列表是否与旧列表不同,有两个szenarios:
a) 如果已知新列表是旧列表的子列表,只需检查上文计算的
已删除
中是否有任何元素。

b) 如果新列表中可能有新的电子邮件,请检查
已删除的
是否包含任何电子邮件,如果没有,请另外检查
len(新电子邮件列表)==len(旧电子邮件列表)

首先,在
if
条件下,您已经在做艰苦的工作,因此不需要事先进行测试。 第二,不清楚你的出发点是什么,是ID还是电子邮件,或者两者中的任何一个,以及你的终点

但似乎最干净的方法是一直使用
set

我认为您可以使用ID(但同样的代码适用于电子邮件地址):


现在,让我们假设起点是两个
列表
(同样,ID或电子邮件是不相关的,为了简单起见,我只假设ID),并假设您想知道添加和删除的项目。有两种可能的方法:

def diffs_set(a, b):
    a = set(a)
    b = set(b)
    return a - b, b - a
对于某些输入大小,其计时如下所示:

funcs = diffs_set, diffs_loop, diffs_loop2, diffs_np
for n in (10, 100, 1000, 10000):
    print(n)
    old_items = list(range(1, n))
    new_items = list(range(n - 1))
    for func in funcs:
        print(func.__name__)
        %timeit func(old_items, new_items)
    print()
# 10
# diffs_set
# The slowest run took 4.52 times longer than the fastest. This could mean that an intermediate result is being cached.
# 1000000 loops, best of 3: 914 ns per loop
# diffs_loop
# 1000000 loops, best of 3: 1.97 µs per loop
# diffs_loop2
# 100000 loops, best of 3: 2.09 µs per loop
# diffs_np
# 10000 loops, best of 3: 65.6 µs per loop

# 100
# diffs_set
# 100000 loops, best of 3: 5.23 µs per loop
# diffs_loop
# 100000 loops, best of 3: 13.6 µs per loop
# diffs_loop2
# 10000 loops, best of 3: 116 µs per loop
# diffs_np
# The slowest run took 5.74 times longer than the fastest. This could mean that an intermediate result is being cached.
# 10000 loops, best of 3: 65.9 µs per loop

# 1000
# diffs_set
# 10000 loops, best of 3: 57.7 µs per loop
# diffs_loop
# 10000 loops, best of 3: 132 µs per loop
# diffs_loop2
# 100 loops, best of 3: 10.7 ms per loop
# diffs_np
# 1000 loops, best of 3: 374 µs per loop

# 10000
# diffs_set
# 1000 loops, best of 3: 818 µs per loop
# diffs_loop
# 1000 loops, best of 3: 1.6 ms per loop
# diffs_loop2
# 1 loop, best of 3: 1.06 s per loop
# diffs_np
# 100 loops, best of 3: 3.5 ms per loop
最重要的一点是,使用集合可以获得最快、最干净的方法。 需要注意的是,
set
s甚至对于
列表的理解也很有用,因为
if
条件变为
O(1)
(导致总体
O(n)
)而不是
O(n)
(导致总体
O(n²)
)。 因为最昂贵的操作是在开始时实际构建
,所以如果只需要
a-b
b-a
,列表理解可能会与仅使用集竞争,因为这样只需要一个
set()
调用。
相反,基于NumPy的方法在这里没有竞争力。

首先,在
if
条件下,您已经在做艰苦的工作,因此不需要事先进行测试。 第二,不清楚你的出发点是什么,是ID还是电子邮件,或者两者中的任何一个,以及你的终点

但似乎最干净的方法是一直使用
set

我认为您可以使用ID(但同样的代码适用于电子邮件地址):


现在,让我们假设起点是两个
列表
(同样,ID或电子邮件是不相关的,为了简单起见,我只假设ID),并假设您想知道添加和删除的项目。有两种可能的方法:

def diffs_set(a, b):
    a = set(a)
    b = set(b)
    return a - b, b - a
对于某些输入大小,其计时如下所示:

funcs = diffs_set, diffs_loop, diffs_loop2, diffs_np
for n in (10, 100, 1000, 10000):
    print(n)
    old_items = list(range(1, n))
    new_items = list(range(n - 1))
    for func in funcs:
        print(func.__name__)
        %timeit func(old_items, new_items)
    print()
# 10
# diffs_set
# The slowest run took 4.52 times longer than the fastest. This could mean that an intermediate result is being cached.
# 1000000 loops, best of 3: 914 ns per loop
# diffs_loop
# 1000000 loops, best of 3: 1.97 µs per loop
# diffs_loop2
# 100000 loops, best of 3: 2.09 µs per loop
# diffs_np
# 10000 loops, best of 3: 65.6 µs per loop

# 100
# diffs_set
# 100000 loops, best of 3: 5.23 µs per loop
# diffs_loop
# 100000 loops, best of 3: 13.6 µs per loop
# diffs_loop2
# 10000 loops, best of 3: 116 µs per loop
# diffs_np
# The slowest run took 5.74 times longer than the fastest. This could mean that an intermediate result is being cached.
# 10000 loops, best of 3: 65.9 µs per loop

# 1000
# diffs_set
# 10000 loops, best of 3: 57.7 µs per loop
# diffs_loop
# 10000 loops, best of 3: 132 µs per loop
# diffs_loop2
# 100 loops, best of 3: 10.7 ms per loop
# diffs_np
# 1000 loops, best of 3: 374 µs per loop

# 10000
# diffs_set
# 1000 loops, best of 3: 818 µs per loop
# diffs_loop
# 1000 loops, best of 3: 1.6 ms per loop
# diffs_loop2
# 1 loop, best of 3: 1.06 s per loop
# diffs_np
# 100 loops, best of 3: 3.5 ms per loop
最重要的一点是,使用集合可以获得最快、最干净的方法。 需要注意的是,
set
s甚至对于
列表的理解也很有用,因为
if
条件变为
O(1)
(导致总体
O(n)
)而不是
O(n)
(导致总体
O(n²)
)。 因为最昂贵的操作是在开始时实际构建
,所以如果只需要
a-b
b-a
,列表理解可能会与仅使用集竞争,因为这样只需要一个
set()
调用。
相反,基于NumPy的方法在这里没有竞争力。

到底什么是
旧的
新的
呢?谢谢你的关注,我会更新我的问题,所以它们是电子邮件地址。。。我猜是字符串还是字节。但是代码似乎无效。很好的评论。事实上,我比较的是ID,而不是电子邮件。您是否考虑添加电子邮件,因为这永远不会发生?确切地说,
旧的
新的
是什么?谢谢您的关注,我会更新我的问题,所以,它们是电子邮件地址。。。我猜是字符串还是字节。但是代码似乎无效。很好的评论。事实上,我比较的是ID,而不是电子邮件。你不打算添加电子邮件吗,因为这永远不会发生?我需要知道列表是否已更改。然后-1)选择已删除的电子邮件以通知他们-2)向新列表发送另一封不同的邮件。有关检查它们是否不同的信息,请参阅我的编辑。你的问题中没有提到第1)点和第2)点,是吗?你到底有什么问题
def diffs_loop2(a, b):
    return [x for x in a if x in b], [x for x in b if x in a]
def diffs_np(a, b):
    return np.setdiff1d(a, b, assume_unique=True), np.setdiff1d(b, a, assume_unique=True)
funcs = diffs_set, diffs_loop, diffs_loop2, diffs_np
for n in (10, 100, 1000, 10000):
    print(n)
    old_items = list(range(1, n))
    new_items = list(range(n - 1))
    for func in funcs:
        print(func.__name__)
        %timeit func(old_items, new_items)
    print()
# 10
# diffs_set
# The slowest run took 4.52 times longer than the fastest. This could mean that an intermediate result is being cached.
# 1000000 loops, best of 3: 914 ns per loop
# diffs_loop
# 1000000 loops, best of 3: 1.97 µs per loop
# diffs_loop2
# 100000 loops, best of 3: 2.09 µs per loop
# diffs_np
# 10000 loops, best of 3: 65.6 µs per loop

# 100
# diffs_set
# 100000 loops, best of 3: 5.23 µs per loop
# diffs_loop
# 100000 loops, best of 3: 13.6 µs per loop
# diffs_loop2
# 10000 loops, best of 3: 116 µs per loop
# diffs_np
# The slowest run took 5.74 times longer than the fastest. This could mean that an intermediate result is being cached.
# 10000 loops, best of 3: 65.9 µs per loop

# 1000
# diffs_set
# 10000 loops, best of 3: 57.7 µs per loop
# diffs_loop
# 10000 loops, best of 3: 132 µs per loop
# diffs_loop2
# 100 loops, best of 3: 10.7 ms per loop
# diffs_np
# 1000 loops, best of 3: 374 µs per loop

# 10000
# diffs_set
# 1000 loops, best of 3: 818 µs per loop
# diffs_loop
# 1000 loops, best of 3: 1.6 ms per loop
# diffs_loop2
# 1 loop, best of 3: 1.06 s per loop
# diffs_np
# 100 loops, best of 3: 3.5 ms per loop