Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.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
Python 使用映射迭代器测试集合交集_Python_Python 3.x - Fatal编程技术网

Python 使用映射迭代器测试集合交集

Python 使用映射迭代器测试集合交集,python,python-3.x,Python,Python 3.x,我试图写一个函数来找到一个弱Sidon序列,一个序列ai,其中ai+aj对于任意长度的所有I

我试图写一个函数来找到一个弱Sidon序列,一个序列ai,其中ai+aj对于任意长度的所有I 这就是我到目前为止所做的:

def weakSidon(sequence_length):
    """Finds a weak Sidon sequence (a sequence (a_i) of integers where a_i + a_j for i < j are all unique) of the necessary length."""
    sequence = [1]
    sums = []
    while len(sequence) < sequence_length:
        test_integer = sequence[-1] + 1
        test_sums = list(map(lambda x: test_integer + x, sequence))
        while any(x in list(test_sums) for x in sums):
            test_integer = test_integer + 1
            test_sums = list(map(lambda x: test_integer + x, sequence))
        sequence.append(test_integer)
        sums = sums + test_sums
    return sequence
这是可行的,正如我在做了这件事之后意识到的那样,这是一种愚蠢的方法,在没有第一个元素的情况下生成斐波那契序列,但是将映射迭代器转换为一个列表,然后在下一行的生成器中立即对其进行迭代似乎很愚蠢,如果可能的话,我想知道如何在将来避免这种混乱

当然,对于简化的任何其他一般性建议,特别是对于重复测试和赋值,我们都表示赞赏。

为某个迭代器a计算a中的x将消耗部分或全部a。评估lista将消耗所有的a。在生成程序x In LISTEST_SUMMES for x In SUMMES中,表达式x In LISTEST_SUMMES针对SUMMES中的每个元素计算一次

因此,如果您没有立即列出map的结果,那么您在listtest_sums中为x in sums检查x将无法按预期工作-当sums中的后续元素得到测试时,test_sums已经被使用,表达式listtest_sums为[]。我发现在解释器中查看这种情况的一个简单示例很有帮助

Python实际上有一个内置的set数据类型。确定集合中的成员身份是一个固定时间的操作,因此,如果您正在进行大量的成员身份检查,那么使用它们是一个好主意。但我们实际上可以去掉a for x in b结构中的anyx,因为Python还定义了集合上的交集和并集。如果a和b是两个集合,那么a | b是它们的并集,a&b是它们的交集

因此,使用集合的代码将是:

def weakSidon(sequence_length):
    sequence = [1]
    sums = set()
    while len(sequence) < sequence_length:
        test_integer = sequence[-1] + 1
        test_sums = {test_integer + n for n in sequence}
        while test_sums & sums:
            test_integer += 1
            test_sums = {test_integer + n for n in sequence}
        sequence.append(test_integer)
        sums |= test_sums
    return sequence
|=运算符是to |什么+=是to+


我以前从未听说过Sidon序列,但我认为Fibonaccis最终成为一个序列真的很有趣。

您的代码有两个主要问题

首先,每次测试一个和是否在测试和列表中时,您都调用列表。listtest_和中的allx和中的x和调用列表很多次,由于test_和已经是一个列表,这只是浪费了周期

第二个问题是,列表成员资格测试通常很慢,即使您没有首先复制列表。测试集合中的成员身份要快得多,所以您可能应该在这里使用一个

如果将求和设置为一个集合,并更改在all调用中迭代的序列,以利用快速集合的优势。_contain__测试,您将得到如下结果:

def weakSidon(sequence_length):
    """Finds a weak Sidon sequence (a sequence (a_i) of integers where
       a_i + a_j for i < j are all unique) of the necessary length."""
    sequence = [1]
    sums = set()                                   # start with an empty set
    while len(sequence) < sequence_length:
        test_integer = sequence[-1] + 1
        test_sums = list(map(lambda x: test_integer + x, sequence))
        while any(x in sums for x in test_sums):   # testing set membership is O(1)
            test_integer = test_integer + 1
            test_sums = list(map(lambda x: test_integer + x, sequence))
        sequence.append(test_integer)
        sums.update(test_sums)                     # update set items
    return sequence

您无法取消一个list调用以将映射生成器转换为实际列表,因为如果没有冲突,您需要在更新步骤中再次访问test_sums值。

为什么不使用set而不是list,对于求和和和和?请注意,当您只需要知道交集是否为非空时,进行全集交集可能会过分。这是因为即使在发现第一个重叠之后,它也会继续相互测试集合项。如果您使用了任何一种,一旦发现第一次碰撞,测试就会短路。@Blckknght正确点。另外,看着你的答案,我意识到测试和根本不需要是一个集合。吹毛求疵:我推荐[x+test\u integer for x in sequence]作为listmaplambda x更可读的替代品:test\u integer+x,sequence。查看集合文档,我发现有一个isdisjoint方法。这可能是一个更优雅的解决方案吗?我假设它的工作原理与这里的any调用类似。