0

I am trying to write python code that takes words from an array and makes a new array that includes all of the longest words of the previous array. I can't find where the problem is, but whenever I run this, it just eats a ton of RAM but doesn't work (it should print the words Good and Cool). Does anyone see the problem?

words = ["Good", "Bad", "Cool"]
def longest_word():
    longest = [""]
    for word in words:
        for word2 in longest:
            if len(word) > len(word2):
                longest.clear()
                longest.append(word)
            elif len(word) == len(word2):
                longest.append(word)
    print(str(longest_word))
longest_word()
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
David
  • 3
  • 1
  • Should `print(str(longest_word))` be `print(longest)`? – 0x5453 Dec 02 '21 at 22:14
  • 1
    I think the problem you are experiencing comes from modifying `longest` while you are iterating over it. – 0x5453 Dec 02 '21 at 22:15
  • 1
    Does this answer your question? [Strange result when removing item from a list while iterating over it](https://stackoverflow.com/questions/6260089/strange-result-when-removing-item-from-a-list-while-iterating-over-it) – Woodford Dec 02 '21 at 22:17

3 Answers3

2

You could do this in a list comprehension using the max function like this:

words = ["Good", "Bad", "Cool"]
max_length = len(max(words,key=len))
longest = [word for word in words if len(word) == max_length]

The max function will return the string with the most characters because of the key=len argument, and then you compare the length of each word in your list to the length of the returned string from max. If the lengths match then it adds the word to the longest list.

Edit: Changed my answer to reflect @NathanielFord's suggestion

Nathan Roberts
  • 828
  • 2
  • 10
  • I would really pull the `len(max(words, key=len))` out of the comprehension and set it to some other variable for the comparison - otherwise you turn a O(n) operation into an O(n^2) operation, since `max` will run through the list each time. – Nathaniel Ford Dec 02 '21 at 22:36
  • @NathanielFord oh didn't think about that. I will do that. – Nathan Roberts Dec 02 '21 at 22:50
0

You could just loop through once getting the length of each word and saving it to a longestWord variable if it's greater. Then loop through a second time to add it to the array if it's the same length as the longestWord variable.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Jerry Spice
  • 63
  • 1
  • 8
0

While I wouldn't go about it this way, you're pretty close with a few simplifications:

words = ["Good", "Bad", "Cool"]
def longest_word():
    longest = []  # Don't add an empty word here
    l = len(words[0])  # Remember the length of the first word
    for word in words:
        if len(word) > l:  # If the next word is longer than the longest length found so far...
            longest = []  # Reset your list
            longest.append(word)  # Add the word
            l = len(word)  # Remember the new longest length
        elif len(word) == l:
            longest.append(word)
    
    print(longest)
longest_word()

There are two reasons not to iterate over the longest list. The first is that you're actively modifying that list - if you clear it in the middle of doing so it will lead to strange results. Secondly, it's much more computationally expensive - you might get O(n^2) time in the worst case. The only info you need is the length so far of the longest word, so remember that and update it instead of trying to recheck each element of your longest list. (After all, you know all those elements have to equal each other!)

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • Thanks, your code has fixed it. Since this is my first question ever, how do I close it as solved? – David Dec 03 '21 at 05:46
  • @David You should upvote any answer that has helped you, and then choose one as 'accepted'. On the left of the answers are numbers with arrows above and a checkmark below. The checkmark is for 'accepted' and the arrows are for 'helped' (up) and 'not a good answer' (down). Generally it's best to upvote! – Nathaniel Ford Dec 03 '21 at 06:45