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 '20 at 21:08
  • \$\begingroup\$ If I replace my "print" with "return", would it be correct? \$\endgroup\$ – Nick Dec 11 '20 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 '20 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 '20 at 1:27
  • \$\begingroup\$ Given the original intent of the post I'm leaning toward the former. \$\endgroup\$ – Reinderien Dec 12 '20 at 15:35
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 '20 at 20:45
  • 2
    \$\begingroup\$ You can, it's just redundant. \$\endgroup\$ – Reinderien Dec 12 '20 at 20:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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