admin管理员组

文章数量:1332359

I'm writing a program in Python to find the shortest and longest strings in an array, e.g. this is find_shortest:

def find_shortest(words):
 
    N = len(words)
    shortest = words[0]
    i = 1
    while i < N:
        if len(shortest) >= len(words[i]): #Change only this line for find_longest
            shortest = words[i]
        i += 1

    return shortest

My problem is that the find_longest function is identical to the find_shortest function, except find_longest uses a <= sign instead of >=. I don't want to copy/paste the find_shortest function to make find_longest but I see no alternative. How do I avoid copy/pasting and redundancy in this scenario?

I'm writing a program in Python to find the shortest and longest strings in an array, e.g. this is find_shortest:

def find_shortest(words):
 
    N = len(words)
    shortest = words[0]
    i = 1
    while i < N:
        if len(shortest) >= len(words[i]): #Change only this line for find_longest
            shortest = words[i]
        i += 1

    return shortest

My problem is that the find_longest function is identical to the find_shortest function, except find_longest uses a <= sign instead of >=. I don't want to copy/paste the find_shortest function to make find_longest but I see no alternative. How do I avoid copy/pasting and redundancy in this scenario?

Share Improve this question edited Nov 23, 2024 at 19:20 mkrieger1 23.3k7 gold badges64 silver badges81 bronze badges asked Nov 21, 2024 at 2:14 anfanf 435 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 0

You could create a comparison function to use based on what "mode" the function is in

def find(words, mode):
    compare = (lambda x, y: x >= y) if mode == 'shortest' else (lambda x, y: x <= y)
    N = len(words)
    result = words[0]
    i = 1
    while i < N:
        if compare(len(result), len(words[i])):
            result = words[i]
        i += 1
    
    return result

where mode is the value 'shortest' or 'longest'. Could be simplified to just a boolean if you want. I used a string just for clarity.

You can add a flag as a parameter, and based on it, choose the corresponding comparison, something like:

def find_shortest( words, short ):
    shortest = words[ 0 ]
    i = 1
    while i < len( words ):
        if short:
            if len( shortest ) >= len( words[ i ] ): 
                shortest = words[ i ]
        else:
            if len( shortest ) <= len( words[ i ] ): 
                shortest = words[ i ]
        i += 1

    return shortest
    
word = "A short word are in Mexico"
words = word.split( " " )
print( find_shortest( words, True ))
print( find_shortest( words, False ))

Just use the normal way and you barely have any code to repeat:

def find_shortest(words):
    return min(words, key=len)

def find_longest(words):
    return max(words, key=len)

And I really wouldn't write extra functions for this, just use min/max directly.

(These find the first shortest/longest instead of the last like yours would. Though you talk about "the" shortest, so apparently you don't have ties. But if you do and it matters, you can use min(reversed(words), key=len)).

You can based on the function argument, as example an order parameter, define the operation that you want to do. Put an if to identify if the operation: if "shortest" do shortest action, if not, do the longest action. It will put some logic, but can help to avoid the function repetition and the same scope can be used.

The function can be simplified by iterating using a for loop.

def find_shortest(words):
    shortest = words[0]
    for word in words:
        if len(shortest) >= len(word):
            shortest = word

    return shortest

At which point trying to reuse such trivial code leads to more complicated and slower code; sometimes cut & paste is fine.

本文标签: