Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.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 - Fatal编程技术网

如何使我的Python代码更加高效?

如何使我的Python代码更加高效?,python,Python,我试图执行的程序有以下问题陈述: 程序必须接受N个包含1到N个整数的整数 以任何顺序复制。程序必须打印丢失的文件 给定整数中从1到N的整数,按升序排列为 输出 例如: 投入:5 25511 产出:3 4 说明:5个整数2中缺少整数3和4 1 1. 因此,3和4被打印为输出 我的代码: def modusoperandi(n, t): if str(n) not in t: yield n n = int(input()) t = tuple(sr for sr in

我试图执行的程序有以下问题陈述:

程序必须接受N个包含1到N个整数的整数 以任何顺序复制。程序必须打印丢失的文件 给定整数中从1到N的整数,按升序排列为 输出

例如:

投入:5

25511

产出:3 4

说明:5个整数2中缺少整数3和4 1 1. 因此,3和4被打印为输出

我的代码:

def modusoperandi(n, t):
    if str(n) not in t:
        yield n 

n = int(input())
t = tuple(sr for sr in input().split())
for i in range(1,n+1):
    for j in modusoperandi(i,t):
        print(j,end=' ')
然而,我的代码未能通过所有测试用例,因为对于输入量巨大的测试用例执行需要相当长的时间[需要超过500毫秒,这是时间限制]


我尝试使用timeit方法计算执行时间。奇怪的是,当元组中的元素数量增加时,对于给定的N,执行时间也会增加。我更喜欢元组而不是列表,因为它应该更有效。

您需要将现有的数字转换为整数,然后将它们放在一个集合中;集合对于确定给定值是否为成员非常有效

n=初始输入 extant=input.split中n的setintn 对于范围1中的i,n+1: 如果我不是现存的: 打印,结束=
您需要将现有的数字转换为整数,然后将它们放入一个集合中;集合对于确定给定值是否为成员非常有效

n=初始输入 extant=input.split中n的setintn 对于范围1中的i,n+1: 如果我不是现存的: 打印,结束= 印刷品:

3 4 
印刷品:

3 4 

您应该考虑解决方案的复杂性,这是非常糟糕的:

def modusoperandi(n, t):
    # Since 't' is a tuple, the complexity of 'not in t' is O(len(t))
    # This makes the overall complexity of this function O(len(t))
    if str(n) not in t:
        yield n 

n = int(input())
t = tuple(sr for sr in input().split()) # O(len(t))
for i in range(1,n+1):  # O(n) iterations

    # 0 or 1 iteration, but the call to 'modusoperandi' is O(len(t))
    for j in modusoperandi(i,t):  
        print(j,end=' ')
四旬斋的整体复杂性。这不是一个很好的复杂性。您希望输入的复杂性是线性的。有两种方法:

使用哈希表标记所有访问的整数,set就是这样一个哈希表。不幸的是,哈希表有一些缺点。 由于有n个条目,且数字在1..n范围内,因此使用遇到的特征向量值是非常有效的,其中遇到的值[i]在且仅在遇到i值时为真。对于此类大输入,此解决方案可能比集合运行得更快,并且消耗更少的内存。


您应该考虑解决方案的复杂性,这是非常糟糕的:

def modusoperandi(n, t):
    # Since 't' is a tuple, the complexity of 'not in t' is O(len(t))
    # This makes the overall complexity of this function O(len(t))
    if str(n) not in t:
        yield n 

n = int(input())
t = tuple(sr for sr in input().split()) # O(len(t))
for i in range(1,n+1):  # O(n) iterations

    # 0 or 1 iteration, but the call to 'modusoperandi' is O(len(t))
    for j in modusoperandi(i,t):  
        print(j,end=' ')
四旬斋的整体复杂性。这不是一个很好的复杂性。您希望输入的复杂性是线性的。有两种方法:

使用哈希表标记所有访问的整数,set就是这样一个哈希表。不幸的是,哈希表有一些缺点。 由于有n个条目,且数字在1..n范围内,因此使用遇到的特征向量值是非常有效的,其中遇到的值[i]在且仅在遇到i值时为真。对于此类大输入,此解决方案可能比集合运行得更快,并且消耗更少的内存。


关键是使用集合来检查输入字符串中是否存在预期的数字。不过,您不需要将输入转换为整数。您可以通过将序列号生成为字符串来实现这一点

nums    = input().split()
numSet  = set(nums)
missing = " ".join(str(n) for n in range(1,len(nums)+1) if str(n) not in numSet)

print(missing) # 3 4
对于此特定问题,有一种比使用集合更快的替代方法,因为您可以创建具有已知且合理大小的标志数组:

numbers = input().split()
present = [False]*len(numbers)
for n in numbers: present[int(n)-1] = True
missing = " ".join(str(n+1) for n,seen in enumerate(present) if not seen)

关键是使用集合来检查输入字符串中是否存在预期的数字。不过,您不需要将输入转换为整数。您可以通过将序列号生成为字符串来实现这一点

nums    = input().split()
numSet  = set(nums)
missing = " ".join(str(n) for n in range(1,len(nums)+1) if str(n) not in numSet)

print(missing) # 3 4
对于此特定问题,有一种比使用集合更快的替代方法,因为您可以创建具有已知且合理大小的标志数组:

numbers = input().split()
present = [False]*len(numbers)
for n in numbers: present[int(n)-1] = True
missing = " ".join(str(n+1) for n,seen in enumerate(present) if not seen)

您能否解释一下,将数字转换为int(而不是保留为str)以及在元组/列表上使用集合如何减少代码的耗时?比较两个整数,只要它们适合平台的32位或64位,就需要一个汇编操作。比较两个字符串需要分别查看每个字符并移动到下一个字符。检查列表中是否存在元素需要查看列表中的所有元素。检查集合中是否存在元素需要对值进行哈希运算并检查一个或一小部分元素。Jeffrey说,此外,您也不会花时间将i从范围往返到str进行比较。您能解释一下如何将数字转换为int(而不是保留为str)并在元组/列表上使用集合来减少代码耗时吗?比较两个整数,只要它们适合平台的32位或64位,就需要一个汇编操作。比较两个字符串需要分别查看每个字符并移动到下一个字符。检查列表中是否存在元素需要查看列表中的所有元素。Chec
要确定集合中是否存在元素,需要对值进行哈希运算,并检查一个或一小部分元素。正如Jeffrey所说,而且您也不会花时间将i从范围往返到STR进行比较。基于.nbytes,看起来dtype=bool数组没有打包—每个值只有一个字节,即使你很聪明,能把8个布尔值打包成一个字节。@AKX这并不让我感到惊讶。但即使没有包装,它的紧凑性也是setrangen的30多倍,而且运行速度比setrangen快得多!当然,这需要numpy,如果我理解正确的话,在OP的案例中,在线判断环境是不可能的。@AKX我怀疑你是对的。答案的关键是给出另一种方法,而不是填鸭式的。如果愿意,同样的方法也可以通过常规列表实现,而不需要numpy。如果是C,这种方法会比使用setYep的方法简单得多,只是指出了这一点,根本没有试图淡化你的答案——如果听起来像这样,我很抱歉!基于.nbytes,看起来dtype=bool数组并没有打包-它是每个值一个字节,即使您可以聪明地将8个bool打包成一个字节。@AKX这并不让我感到惊讶。但即使没有包装,它的紧凑性也是setrangen的30多倍,而且运行速度比setrangen快得多!当然,这需要numpy,如果我理解正确的话,在OP的案例中,在线判断环境是不可能的。@AKX我怀疑你是对的。答案的关键是给出另一种方法,而不是填鸭式的。如果愿意,同样的方法也可以通过常规列表实现,而不需要numpy。如果是C,这种方法会比使用setYep的方法简单得多,只是指出了这一点,根本没有试图淡化你的答案——如果听起来像这样,我很抱歉!另一方面,由于簿记中的内部开销,使用收益率的生成器(如操作方式)通常比常规函数慢。另一方面,由于簿记中的内部开销,使用收益率的生成器(如操作方式)通常比常规函数慢。