I'm making a code that receive a list of phone numbers and then checks if one or more of the numbers is a prefix of other numbers in the list. I want to optimize to the maximum so that it can run as fast as possible. Here's the code:
cases = []
t = int(input())
for i in range(0, t):
n = int(input())
case = []
for j in range(0, n):
case.append(str(input()))
cases.append(sorted(case))
print(cases)
for c in cases:
answer = 'YES'
for k in range(0, len(c)):
if answer == 'YES':
for l in range(0, len(c)):
if c[k] != c[l]:
if c[k] == c[l][0:len(c[k])]:
answer = 'NO'
break
else:
break
print(answer)
Edit: Using the answer proposed by @Gelineau, the code run in 0.82s, being that before it went from >3s to reach the solution. With that now the solution looks like this:
cases = []
t = int(input())
for i in range(0, t):
n = int(input())
case = []
for j in range(0, n):
case.append(str(input()))
cases.append(case)
for case in cases:
answer = 'YES'
case.sort()
for case_k, case_next in zip(case, case[1:]):
if case_k == case_next[:len(case_k)]:
answer = 'NO'
break
print(answer)
ktzr's answer requires n*n comparisons, with n = len(case). You could sort case first (n * log(n) operations), and then you need only compare one case_k with the next one in the list (n operations).
case.sort()
for case_k, case_next in zip(case, case[1:]):
if case_k == case_next[:len(case_k)]:
answer = 'NO'
break
EDITED:
You can also use a generator expression:
case.sort()
answer = all(case_k != case_next[:len(case_k)] for case_k, case_next in zip(case, case[1:]))
(answer will be True or False). It will not be faster, but it is clearer IMHO