peyo
peyo

Reputation: 371

How do you simplify these loops?

def funny_phrases(list):

    funny = []
    for word1 in list:
        if len(word1) >= 6:
            funny.append(word1)

    phrases = []
    for word2 in funny:
        if word2[-1:] is "y":
            phrases.append(word2)
    return phrases


print(funny_phrases(["absolutely", "fly", "sorry", "taxonomy", "eighty", "excellent"]))
print(funny_phrases(["terrible", "normally", "naughty", "party"]))
print(funny_phrases(["tour", "guy", "pizza"]))

I have these loops and was wondering if there were any ways to simplify it.

Upvotes: 0

Views: 132

Answers (3)

def funny_phrases(list):
    return [(l) for l in list if len(l)>6 and l[len(l)-1] == 'y']

print(funny_phrases(["absolutely", "fly", "sorry", "taxonomy", "eighty", "excellent"]))

['absolutely', 'taxonomy']

Upvotes: -1

Ender Look
Ender Look

Reputation: 2401

You are not using nested loop, but you could use filter:

def funny_phrases(words):
    funny = filter(lambda word: len(word) >= 6, words)
    return list(filter(lambda word: word[-1:] is "y", funny))

By the way, as you can see I renamed your parameter list to words because it was overriding the list() function. Try to not call list to your lists, instead use more explaining names.

Or in one line:

def funny_phrases(words):
    return list(filter(lambda word: word[-1:] is "y", filter(lambda word: len(word) >= 6, words)))

Or doing a single iteration:

def funny_phrases(words):
    return list(filter(lambda word: len(word) >= 6 and word[-1:] is "y", words))

Or if you prefer list comprehensions:

def funny_phrases(words):
    return [word for word in words if len(word) >= 6 and word[-1:] is "y"]

In addition, somethings can be improved:

word[-1:] is "y"

That isn't good, instead:

word.endswith("y")

That is more verbose and easier to understand.

So your final could should be one of both:

def funny_phrases(words):
    return [word for word in words if len(word) >= 6 and word.endswith("y")]

def funny_phrases(words):
    return list(filter(lambda word: len(word) >= 6 and word.endswith("y"), words))

I would use list comprehension because they are more verbose in my opinion, but that is up to you.

As @ShadowRanger commented, list comprehension are a rather better choice for this task. They look better and in this case (using lambda) they are faster than filter.

Upvotes: 0

ShadowRanger
ShadowRanger

Reputation: 155363

Test both conditions at once to reduce it to one loop:

def funny_phrases(lst):
    funny = []
    for word in lst:
        if len(word) >= 6 and word.endswith('y'):
            funny.append(word)
    return funny

which can then be translated to a list comprehension, leaving:

def funny_phrases(lst):
    return [word for word in lst if len(word) >= 6 and word.endswith('y')]

Note that I made two small changes beyond the loop improvements:

  1. I changed the variable name to lst to avoid name-shadowing the list constructor (which would have prevented you from using it if you ever needed it)
  2. I changed slicing with magic numbers to the named method .endswith('y'), which is more self-documenting (and doesn't require temporary strs, like slicing would).

Upvotes: 2

Related Questions