1
\$\begingroup\$

This is an exercise in the Automate The Boring Stuff book. I am supposed to create a function that takes a list value as an argument and returns a string with all the items separated by a comma and a space, with 'and' inserted before the last item. My code also includes a loop for the user to create their list.

def add_and(alist):
    if ((alist != []) & (len(alist) > 2)):
        for item in alist[:-1]:
            print(item + ", ",end="")
        print("and", alist[-1])
    elif ((alist != []) & (len(alist) == 2)):
        print(alist[0], "and", alist[1])
    elif ((alist != []) & (len(alist) == 1)):
        print(alist[0])
    else:    
        print("")
        
your_list = []
while True:
    print("Enter An Item or nothing")
    item = input()
    if ((item) == ""):
        print("")
        break
    else:
        your_list.append(item)
        continue

add_and(your_list)

I know that the code works, but I was wondering if there were any faux-pas that I am implementing, or if there is anything I could obviously do to make it cleaner. Thanks!

\$\endgroup\$
5
  • \$\begingroup\$ You've not implemented the correct solution for the question. Your task is to "create a function that ... returns a string". The function you wrote prints the result but returns nothing. \$\endgroup\$
    – AJNeufeld
    Dec 11, 2020 at 21:08
  • \$\begingroup\$ If I replace my "print" with "return", would it be correct? \$\endgroup\$
    – Nick
    Dec 11, 2020 at 21:26
  • \$\begingroup\$ The last two in the function could be replaced by return, the middle one would need modification, but could also be replaced. But the first two cannot be. You can only return from a function once, not multiple time in a loop; the first return executed terminates the function. \$\endgroup\$
    – AJNeufeld
    Dec 12, 2020 at 1:23
  • \$\begingroup\$ You can edit the question to match what the code does, and then we can review what you have written, or we can attempt to migrate the code to Stack Overflow, where you might get assistance with fixing the code to do what the problem asks. Which would you prefer? \$\endgroup\$
    – AJNeufeld
    Dec 12, 2020 at 1:27
  • \$\begingroup\$ Given the original intent of the post I'm leaning toward the former. \$\endgroup\$
    – Reinderien
    Dec 12, 2020 at 15:35

1 Answer 1

2
\$\begingroup\$
  • Don't surround sub-predicates or predicates with parens when that isn't needed
  • Use logical and rather than binary &
  • Use join rather than a for-and-concatenate
  • Factor out common sub-predicates for your list emptiness checks into an outer if
  • Don't else-after-break
  • No need to continue
  • Gather your input in a separate function
  • Do not leave the input prompt blank

Suggested:

def and_add(alist):
    if len(alist) > 1:
        print(', '.join(alist[:-1]), 'and', alist[-1])
    elif len(alist) == 1:
        print(alist[0])
    else:
        print('')

def get_input():
    while True:
        item = input('Enter an item or nothing: ')
        if not item:
            return
        yield item

and_add(list(get_input())) 
\$\endgroup\$
2
  • \$\begingroup\$ Thanks! Why can't you else-after-break? \$\endgroup\$
    – Nick
    Dec 12, 2020 at 20:45
  • 2
    \$\begingroup\$ You can, it's just redundant. \$\endgroup\$
    – Reinderien
    Dec 12, 2020 at 20:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.