简体   繁体   中英

More efficient way to handle big lists in python?

I'm writing a python script to solve this exercise:

Given in input a vector V of N integers we want to find, for each size between 1 and N, the maximum of the minimum's of every contiguous subsequence in the vector.

The script I wrote works fine with N<1000 but when I try it with greater values, it just keeps running without ending. I guessed it's too slow because of the 3 for-loops and the many.append() to big lists, but how can I solve that? Or am I wrong and there is another problem I don't see?

f_name = input("Inserire nome del file: ")
 
f_in = open("inputs/"+f_name, "r")
f_out = open("outputs/"+f_name, "w")
 
# n = int(input())
n = int(f_in.readline())
 
v_s = f_in.readline().rstrip('\n').split()
v = [int(i) for i in v_s]
 
maxs = []
 
for size in range(1, n+1):
    mins = []
    for i in range(n):
        subseq = []
        if (i+size <= n):
            for j in range(size):
                subseq.append(v[i+j])
        if (len(subseq) > 0):
            mins.append(min(subseq))
    maxs.append(max(mins))
 
for max in maxs:
    f_out.write(str(max) + " ")
 
f_in.close()
f_out.close()

Here are some examples of input and output.

The appends in python are pretty fast, but your algorithm is too slow -- you have three nested loops which have on the order of N elements each, with total complexity of O(n^3).

This means that with careful optimization, maybe you can handle 2000 values or 3000 values... but your biggest example is 500000 values, so this is not going to help.

If you want to solve this, you need to rewrite the program so it does not have three nested loops. This problem is well-known, and you can find solutions on the internet with no nested loops, O(n) complexity.

Try this:

from numpy import array_split

f_name = input("Inserire nome del file: ")

with open("{}/{}".format("inputs", f_name), "r") as fp:
    lines = fp.readlines()

n = int(lines[0])
v = [int(s.strip()) for s in lines[-1].split()]

maxs = []
n += 1
for i in range (1 , n):
    my_mins = [min(val) for val in array_split(v, i)] 
    maxs.append(max(my_mins))

output = [str(m) for m in maxs]
output = " ".join(output)

with open("{}/{}".format("outputs", f_name), "w") as fp:
    fp.write(output)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM