Mars Lee
Mars Lee

Reputation: 1945

Why these two almost same codes have different efficient (Python)?

I was practicing programming by Python on leetcode.

So this is the problem: https://leetcode.com/problems/reverse-vowels-of-a-string/

And this is my answer:

def reverseVowels(s):
    result = list(s)
    v_str = 'aeiouAEIOU'
    v_list = [item for item in s if item in v_str]
    v_list.reverse()
    v_index = 0
    for i, item in enumerate(s):
        if item in v_list:
            result[i] = v_list[v_index]
            v_index+=1
    return ''.join(result)

The result: Time Limit Exceeded

And I found an extremely similar answer in the discussion:

def reverseVowels(s):
    lst = list(s)
    vowels_str = "aeiouAEIOU"
    vowels_list = [item for item in lst if item in vowels_str]
    vowels_list.reverse()
    vowels_index = 0
    for index, item in enumerate(lst):
        if item in vowels_str:
            lst[index] = vowels_list[vowels_index]
            vowels_index += 1
    return ''.join(lst)

The result: Accepted

This is so weird. I think these two code seem exactly the same.

The difference of them is nothing but parameters.

I am curious about why these codes cause distinct results.

Upvotes: 0

Views: 83

Answers (2)

T. Claverie
T. Claverie

Reputation: 12246

There are two different lines between both codes. First one is:

  • for index, item in enumerate(lst):
  • for i, item in enumerate(s):

In the first case it iterates through the list and in the second it iterates through the string. There may be some performance loss here but it is not the main problem.

  • if item in vowels_str:
  • if item in v_list:

This is where the running time goes. In the first case (working code) it looks for the character in the string made of vowels, which has constant length. In the second case, it looks for the character in the list of all vowels contained in the string, which can be huge depending of the string given in test.

Upvotes: 3

moreON
moreON

Reputation: 2008

In the first of these you are iterating over the string (s) directly, multiple times. In the second, after converting to a list, you are iterating over that list (lst).

The exact reason this causes a difference is an (admittedly large and probably important for correctness) implementation detail in the python interpreter.

See related question for more discussion: Why is it slower to iterate over a small string than a small list?

Upvotes: 1

Related Questions