【问题标题】:How to Optimize Python Programs如何优化 Python 程序
【发布时间】:2020-04-16 03:02:05
【问题描述】:

我正在尝试解决一个竞赛问题:https://dmoj.ca/problem/ccc18s2。 基本上你会得到一个输入,第一行给出输入的行数,然后你会得到一系列整数(最大值:10^9)。 样本输入:

3

4 3 1

6 5 2

9 7 3

然后程序必须旋转这个网格,直到每列的第一个元素小于每列的第二个元素,依此类推。每行也必须按升序排列。

样本输出:

1 2 3

3 5 7

4 6 9

import sys
n = int(sys.stdin.readline())
row=[]
appendtorow = row.append

for i in range(0,n):
    inputx = (sys.stdin.readline()).rstrip()
    inp = inputx.split(" ")
    appendtorow(inp)

def rotate(row):
    new =[]
    for i in range(0,n):
        temp=[]
        for j in range(0,n):
            temp.append(row[n-1-j][i])
        new.append(temp)
    return new

def printout():
    for i in range(0,n):
        for j in range(0,n):
            x=row[i]
            y=x[j]
            sys.stdout.write(y)
            sys.stdout.write(" ")        
        sys.stdout.write("\n")

def check(row):
    m=False
    g=False
    f=False
    for i in range(0,n):
        for j in range(0,n-1):
            if(row[n-1][i]>row[n-1-j][i]):
                m=True
    for i in range(0,n):
        for j in range(0,n-1):
            if(row[i][0]<row[i][j+1]):
                g=True
    if(g==True and m==True):
        f=True
    return f

flag=0
while(flag==0):
    g=check(row)
    if(g==True):
        printout()
        flag=1
    else:
        row = rotate(row)

按照本指南的建议,我尝试使用标准输入、标准输出和将追加移出循环来提高它的速度:https://wiki.python.org/moin/PythonSpeed/PerformanceTips。但是该程序需要时间限制(1s)的两倍时间(2s),这些似乎没有帮助。

我该如何优化呢? 调用函数会增加程序执行的时间吗?

【问题讨论】:

  • row 对于您的二维数组来说似乎是一个坏名字。但是,您可以在一行中旋转:rotate = zip(*row[::-1]) Source
  • 1) 追加到列表非常慢,如果允许,请使用固定大小的数组; 2)尝试移位和减去列表,然后检查新列表(或更好的数组)的所有元素是否低于/高于零,而不是比较两个列表的每个元素(一个具有不同索引的列表)
  • 在检查程序中,如果条件不满足,您应该尽早跳出双循环。

标签: python python-3.x optimization


【解决方案1】:

认为以下两个模块应该可以提高两个例程的性能(没有重构名称“行”以保留尽可能多的原始代码——但这是一个坏名字)。

rotate - 使用内置函数而不是双重 for 循环的简单单线。

检查 - 当行或列未升序时提前终止循环。

import sys

def rotate(row):
    " Use builtin zip is much faster than double for loops "
    # From -- https://stackoverflow.com/questions/8421337/rotating-a-two-dimensional-array-in-python
    return list(zip(*row[::-1]))

def printout():
    for i in range(0,n):
        for j in range(0,n):
            x=row[i]
            y=x[j]
            sys.stdout.write(y)
            sys.stdout.write(" ")        
        sys.stdout.write("\n")

def check(row):
    " Early terminate when row or column not ascending "

    # Check each row and columns values are incresing
    # Done with single double for loop rather than two sets
    for i in range(1, n):
      for j in range(1, n):
        if not (row[i][j] > row[i][j-1] and row[i][j] > row[i-1][j]):
          # terminate, since not ascending along row or column
          return False

    return True

n = int(sys.stdin.readline())
row=[]
appendtorow = row.append

for i in range(0,n):
    inputx = (sys.stdin.readline()).rstrip()
    inp = inputx.split(" ")
    appendtorow(inp)

flag=0
while(flag==0):
    g=check(row)
    if(g==True):
        printout()
        flag=1
    else:
        row = rotate(row)

【讨论】:

  • 我收到此错误:'zip' 类型的对象在第 24 和 35 行没有 len(),n= len(row)。如果我删除该行,我会得到 'zip' object is not subscriptable
  • @alibiineed--删除 n = len(row)。忘记了 zip(...) 返回一个迭代器所以没有长度,但我们可以使用全局 n。
  • @alibiineed--检查最新代码(另一个要旋转的模组)
  • @alibiineed--重新排列了顺序,因为在 Python 中,函数通常放在脚本代码之前(即文件 I/O 和您拥有的函数的调用)。
【解决方案2】:
import numpy as np
A = np.matrix('4 3 1; 6 5 2; 9 7 3')

check = True

m, n = A.shape
while(check):
    for i in range(m - 1):
        for j in range(n - 1):
            if A[i, j] <= A[i, j + 1] and A[i, j] <= A[i + 1, j]:
                check = check and False
            else:
                check = check and True
    if check == False:
        break;

    A = np.rot90(A)


print(A)

【讨论】:

  • 在这里,每当矩阵不满足您的条件时,您将矩阵旋转 90 度
【解决方案3】:

首先将输入值转换为矩阵格式,然后将每一行按升序排列,然后找到矩阵的转置。
例如:

  1. x=torch.Tensor([4,3,1],[6,5,2],[9,7,3])
  2. 使用torch.sort()
  3. 使用torch.Transpose()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 2023-02-09
    相关资源
    最近更新 更多