Home > Software engineering >  How do I shorten this code with python list comprehension?
How do I shorten this code with python list comprehension?

Time:10-02

I am trying to code this,

def retrieve_smallest_letter(words):
"""
Input: 'words' (lst) which represents a list of strings.
Output: A new list with the smaller letter of the each word's 
          first and last index value compared to be appended to the list.
For Example:
>>> lst = ['sandbox', 'portabello', 'lion', 'australia', 'salamander']
>>> retrieve_smallest_letter(lst)
['s', 'o', 'l', 'a', 'r']
"""

My code

def retrieve_smallest_letter(words):
    lst = []
    for i in range(len(words)):
        first_word = words[i][0]
        last_word = words[i][len(words[i])-1]
        if first_word < last_word:
            lst.append(str(first_word))
        else:
            lst.append(str(last_word))

    return lst

How can I shorten this code with list comprehension?

CodePudding user response:

First thing to understand is that a list comprehension is fundamentally restricted semantics on a for loop:

r = [a for a in b if c]

is essentially syntactic sugar for

r = []
for a in b:
    if c:
        r.append(a)

so the first step is to get the problem into a "shape" which fits a list comprehension:

  • simple iteration and filtering
  • no assignments (because that's as yet not supported)
  • only one production

Using Python correctly also help, do let's start by simplifying the existing loop:

  • iterate collections directly, Python has a powerful iterator protocol and you don't usually iterate by indexing unless absolutely necessary
  • use indexing or destructuring on the word, Python allows indexing from the end (using negative indices)
  • perform the selection "inline" as a single expression, using either a conditional expression or in this case the min builtin which does exactly what's needed
def retrieve_smallest_letter(words):
    lst = []
    for word in words:
        lst.append(min(word[0], word[-1]))

    return lst

or

def retrieve_smallest_letter(words):
    lst = []
    for first, *_, last in words:
        lst.append(min(first, last))

    return lst

from there, the conversion is trivial (there is no filtering so it can be ignored):

def retrieve_smallest_letter(words):
    return [min(first, last) for first, *_, last in words]

CodePudding user response:

Yes

[min(word[0], word[-1]) for word in words]

CodePudding user response:

lst = [min(w[0], w[-1]) for w in words]
  • Related