Comma Code - Ch. 4 Automate the Boring StuffProgram to print a Python list as “a, b, and c”Comma Code (project from “Automate the Boring Stuff with Python”)Comma Code (Python)Comma Code - Automate the Boring StuffPython Automate the Boring Stuff Collatz exerciseAutomate the Boring Stuff - Collatz ExerciseFantasy game inventory — Ch. 5 Automate the Boring StuffRegex version of strip() - Ch. 7 Automate the Boring StuffUsing another function on modified dictionaryComma Code - Automate the Boring Stuff with Python

Noise reduction using multiple recordings of the same signal

What is this second smaller runway next to London City Airport?

Why don't we say a blessing before giving charity?

Why are so many cities in the list of 50 most violent cities in the world located in South and Central America?

How to deal with non-stop callers in the service desk

Greek diacritic with English letter

How can Edward Snowden be denied a jury trial?

Why is more music written in sharp keys than flat keys?

What type of key profile is this?

Can Tankless & Conventional water heaters Join forces?

Is dark matter inside galaxies different from dark matter in intergalactic space?

instead of pressurizing an entire spacesuit with oxygen could oxygen just pressurize the head and the rest of the body be pressurized with water?

Why did the people of Zion never find evidence of the previous cycles?

How does kinetic energy work in braking a vehicle?

Is there a more elegant way to express ((x == a and y == b) or (x == b and y == a))?

Does animal blood, esp. human, really have similar salinity as ocean water, and does that prove anything about evolution?

How much caffeine would there be if I reuse tea leaves in a second brewing?

Would the professor leave the classroom if only 1 student uses their cellphone during class?

Define a command differently in inline vs display mode

Is it possible to commute 34 km (21 miles) daily?

Did the Allies reverse the threads on secret microfilm-hiding buttons to thwart the Germans?

Why does the SR-71 Blackbird sometimes have dents in the nose?

Why are the Ukraine related congressional hearings behind closed doors?

Term for anticipating counterarguments and rebutting them



Comma Code - Ch. 4 Automate the Boring Stuff


Program to print a Python list as “a, b, and c”Comma Code (project from “Automate the Boring Stuff with Python”)Comma Code (Python)Comma Code - Automate the Boring StuffPython Automate the Boring Stuff Collatz exerciseAutomate the Boring Stuff - Collatz ExerciseFantasy game inventory — Ch. 5 Automate the Boring StuffRegex version of strip() - Ch. 7 Automate the Boring StuffUsing another function on modified dictionaryComma Code - Automate the Boring Stuff with Python






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









18














$begingroup$


I am new to programming and currently learning Python using "Automate the Boring" by Al Sweigart. I've just completed the "Comma Code" task in Chapter 4 and would like some feedback on my solution. The task is:




Say you have a list value like this:



spam = ['apples', 'bananas', 'tofu', 'cats']


Write a function that takes a list value as an argument and returns a string with all the items separated by a comma and space, with and inserted before the last item. For example, passing the previous spam list to the function would return 'apples, bananas, tofu, and cats'. But your function should be able to work with any list value passed to it.




I tried to come up with something that mostly sticks to what you learn by this point in the book, but I did use .join() which is from a few chapters later. I also tried to make sure my code works with lists containing strings and/or integers, and for the output to be correct independent of list size (no comma when the list has two items, etc.).



your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

def list_concatenator(your_list):
items = len(your_list)
if items == 0:
return 'Your list is empty'

elif items == 1:
return "'" + str(your_list[0]) + "'"

elif items == 2:
return "'" + str(your_list[0]) + ' and ' + str(your_list[1]) + "'"

else:
your_list_split1 = (', '.join((map(str,your_list[:-1]))))
return "'" + your_list_split1 + ', and ' + str(your_list[-1]) + "'"

list_concatenator(your_list)


I realize these exercises have been answered before, I'm just looking for some feedback on my solution.










share|improve this question












$endgroup$










  • 5




    $begingroup$
    For a two-element list like ['apples', 'bananas'], your code skips the comma and returns 'apples and bananas' rather than 'apples, and bananas' like the spec seems to ask for. Is that intentional? (Also, I suspect you're not supposed to actually wrap the output string in quotes; that's just how the book writes string literals. But I might be mistaken.)
    $endgroup$
    – Ilmari Karonen
    May 30 at 12:02











  • $begingroup$
    @IlmariKaronen - OP is actually trying to implement this.
    $endgroup$
    – Justin
    May 30 at 15:37







  • 2




    $begingroup$
    Don’t signal an error by returning an error message, throw an exception instead. The calling code will know better how exactly to notify the user of the problem.
    $endgroup$
    – Roman Odaisky
    May 31 at 0:07






  • 5




    $begingroup$
    @IlmariKaronen That is almost certainly a failure in the specification. Such formatting would be obviously incorrect punctuation. The description doesn't contain any specific instructions on the case of a two item list and provides only an example of four items. Note that the description doesn't describe what to do in the case of empty or single item lists, either. The OP has extended the specification to handle edge cases that were left unspecified. Another valid approach would be to just throw an error for less than three items.
    $endgroup$
    – jpmc26
    May 31 at 10:37







  • 2




    $begingroup$
    Don't return 'Your list is empty', throw an error!
    $endgroup$
    – Tvde1
    Jun 2 at 10:23

















18














$begingroup$


I am new to programming and currently learning Python using "Automate the Boring" by Al Sweigart. I've just completed the "Comma Code" task in Chapter 4 and would like some feedback on my solution. The task is:




Say you have a list value like this:



spam = ['apples', 'bananas', 'tofu', 'cats']


Write a function that takes a list value as an argument and returns a string with all the items separated by a comma and space, with and inserted before the last item. For example, passing the previous spam list to the function would return 'apples, bananas, tofu, and cats'. But your function should be able to work with any list value passed to it.




I tried to come up with something that mostly sticks to what you learn by this point in the book, but I did use .join() which is from a few chapters later. I also tried to make sure my code works with lists containing strings and/or integers, and for the output to be correct independent of list size (no comma when the list has two items, etc.).



your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

def list_concatenator(your_list):
items = len(your_list)
if items == 0:
return 'Your list is empty'

elif items == 1:
return "'" + str(your_list[0]) + "'"

elif items == 2:
return "'" + str(your_list[0]) + ' and ' + str(your_list[1]) + "'"

else:
your_list_split1 = (', '.join((map(str,your_list[:-1]))))
return "'" + your_list_split1 + ', and ' + str(your_list[-1]) + "'"

list_concatenator(your_list)


I realize these exercises have been answered before, I'm just looking for some feedback on my solution.










share|improve this question












$endgroup$










  • 5




    $begingroup$
    For a two-element list like ['apples', 'bananas'], your code skips the comma and returns 'apples and bananas' rather than 'apples, and bananas' like the spec seems to ask for. Is that intentional? (Also, I suspect you're not supposed to actually wrap the output string in quotes; that's just how the book writes string literals. But I might be mistaken.)
    $endgroup$
    – Ilmari Karonen
    May 30 at 12:02











  • $begingroup$
    @IlmariKaronen - OP is actually trying to implement this.
    $endgroup$
    – Justin
    May 30 at 15:37







  • 2




    $begingroup$
    Don’t signal an error by returning an error message, throw an exception instead. The calling code will know better how exactly to notify the user of the problem.
    $endgroup$
    – Roman Odaisky
    May 31 at 0:07






  • 5




    $begingroup$
    @IlmariKaronen That is almost certainly a failure in the specification. Such formatting would be obviously incorrect punctuation. The description doesn't contain any specific instructions on the case of a two item list and provides only an example of four items. Note that the description doesn't describe what to do in the case of empty or single item lists, either. The OP has extended the specification to handle edge cases that were left unspecified. Another valid approach would be to just throw an error for less than three items.
    $endgroup$
    – jpmc26
    May 31 at 10:37







  • 2




    $begingroup$
    Don't return 'Your list is empty', throw an error!
    $endgroup$
    – Tvde1
    Jun 2 at 10:23













18












18








18


2



$begingroup$


I am new to programming and currently learning Python using "Automate the Boring" by Al Sweigart. I've just completed the "Comma Code" task in Chapter 4 and would like some feedback on my solution. The task is:




Say you have a list value like this:



spam = ['apples', 'bananas', 'tofu', 'cats']


Write a function that takes a list value as an argument and returns a string with all the items separated by a comma and space, with and inserted before the last item. For example, passing the previous spam list to the function would return 'apples, bananas, tofu, and cats'. But your function should be able to work with any list value passed to it.




I tried to come up with something that mostly sticks to what you learn by this point in the book, but I did use .join() which is from a few chapters later. I also tried to make sure my code works with lists containing strings and/or integers, and for the output to be correct independent of list size (no comma when the list has two items, etc.).



your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

def list_concatenator(your_list):
items = len(your_list)
if items == 0:
return 'Your list is empty'

elif items == 1:
return "'" + str(your_list[0]) + "'"

elif items == 2:
return "'" + str(your_list[0]) + ' and ' + str(your_list[1]) + "'"

else:
your_list_split1 = (', '.join((map(str,your_list[:-1]))))
return "'" + your_list_split1 + ', and ' + str(your_list[-1]) + "'"

list_concatenator(your_list)


I realize these exercises have been answered before, I'm just looking for some feedback on my solution.










share|improve this question












$endgroup$




I am new to programming and currently learning Python using "Automate the Boring" by Al Sweigart. I've just completed the "Comma Code" task in Chapter 4 and would like some feedback on my solution. The task is:




Say you have a list value like this:



spam = ['apples', 'bananas', 'tofu', 'cats']


Write a function that takes a list value as an argument and returns a string with all the items separated by a comma and space, with and inserted before the last item. For example, passing the previous spam list to the function would return 'apples, bananas, tofu, and cats'. But your function should be able to work with any list value passed to it.




I tried to come up with something that mostly sticks to what you learn by this point in the book, but I did use .join() which is from a few chapters later. I also tried to make sure my code works with lists containing strings and/or integers, and for the output to be correct independent of list size (no comma when the list has two items, etc.).



your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

def list_concatenator(your_list):
items = len(your_list)
if items == 0:
return 'Your list is empty'

elif items == 1:
return "'" + str(your_list[0]) + "'"

elif items == 2:
return "'" + str(your_list[0]) + ' and ' + str(your_list[1]) + "'"

else:
your_list_split1 = (', '.join((map(str,your_list[:-1]))))
return "'" + your_list_split1 + ', and ' + str(your_list[-1]) + "'"

list_concatenator(your_list)


I realize these exercises have been answered before, I'm just looking for some feedback on my solution.







python beginner python-3.x strings






share|improve this question
















share|improve this question













share|improve this question




share|improve this question








edited May 31 at 16:20









Sᴀᴍ Onᴇᴌᴀ

14.3k6 gold badges26 silver badges95 bronze badges




14.3k6 gold badges26 silver badges95 bronze badges










asked May 30 at 3:09









benbbenb

931 silver badge8 bronze badges




931 silver badge8 bronze badges










  • 5




    $begingroup$
    For a two-element list like ['apples', 'bananas'], your code skips the comma and returns 'apples and bananas' rather than 'apples, and bananas' like the spec seems to ask for. Is that intentional? (Also, I suspect you're not supposed to actually wrap the output string in quotes; that's just how the book writes string literals. But I might be mistaken.)
    $endgroup$
    – Ilmari Karonen
    May 30 at 12:02











  • $begingroup$
    @IlmariKaronen - OP is actually trying to implement this.
    $endgroup$
    – Justin
    May 30 at 15:37







  • 2




    $begingroup$
    Don’t signal an error by returning an error message, throw an exception instead. The calling code will know better how exactly to notify the user of the problem.
    $endgroup$
    – Roman Odaisky
    May 31 at 0:07






  • 5




    $begingroup$
    @IlmariKaronen That is almost certainly a failure in the specification. Such formatting would be obviously incorrect punctuation. The description doesn't contain any specific instructions on the case of a two item list and provides only an example of four items. Note that the description doesn't describe what to do in the case of empty or single item lists, either. The OP has extended the specification to handle edge cases that were left unspecified. Another valid approach would be to just throw an error for less than three items.
    $endgroup$
    – jpmc26
    May 31 at 10:37







  • 2




    $begingroup$
    Don't return 'Your list is empty', throw an error!
    $endgroup$
    – Tvde1
    Jun 2 at 10:23












  • 5




    $begingroup$
    For a two-element list like ['apples', 'bananas'], your code skips the comma and returns 'apples and bananas' rather than 'apples, and bananas' like the spec seems to ask for. Is that intentional? (Also, I suspect you're not supposed to actually wrap the output string in quotes; that's just how the book writes string literals. But I might be mistaken.)
    $endgroup$
    – Ilmari Karonen
    May 30 at 12:02











  • $begingroup$
    @IlmariKaronen - OP is actually trying to implement this.
    $endgroup$
    – Justin
    May 30 at 15:37







  • 2




    $begingroup$
    Don’t signal an error by returning an error message, throw an exception instead. The calling code will know better how exactly to notify the user of the problem.
    $endgroup$
    – Roman Odaisky
    May 31 at 0:07






  • 5




    $begingroup$
    @IlmariKaronen That is almost certainly a failure in the specification. Such formatting would be obviously incorrect punctuation. The description doesn't contain any specific instructions on the case of a two item list and provides only an example of four items. Note that the description doesn't describe what to do in the case of empty or single item lists, either. The OP has extended the specification to handle edge cases that were left unspecified. Another valid approach would be to just throw an error for less than three items.
    $endgroup$
    – jpmc26
    May 31 at 10:37







  • 2




    $begingroup$
    Don't return 'Your list is empty', throw an error!
    $endgroup$
    – Tvde1
    Jun 2 at 10:23







5




5




$begingroup$
For a two-element list like ['apples', 'bananas'], your code skips the comma and returns 'apples and bananas' rather than 'apples, and bananas' like the spec seems to ask for. Is that intentional? (Also, I suspect you're not supposed to actually wrap the output string in quotes; that's just how the book writes string literals. But I might be mistaken.)
$endgroup$
– Ilmari Karonen
May 30 at 12:02





$begingroup$
For a two-element list like ['apples', 'bananas'], your code skips the comma and returns 'apples and bananas' rather than 'apples, and bananas' like the spec seems to ask for. Is that intentional? (Also, I suspect you're not supposed to actually wrap the output string in quotes; that's just how the book writes string literals. But I might be mistaken.)
$endgroup$
– Ilmari Karonen
May 30 at 12:02













$begingroup$
@IlmariKaronen - OP is actually trying to implement this.
$endgroup$
– Justin
May 30 at 15:37





$begingroup$
@IlmariKaronen - OP is actually trying to implement this.
$endgroup$
– Justin
May 30 at 15:37





2




2




$begingroup$
Don’t signal an error by returning an error message, throw an exception instead. The calling code will know better how exactly to notify the user of the problem.
$endgroup$
– Roman Odaisky
May 31 at 0:07




$begingroup$
Don’t signal an error by returning an error message, throw an exception instead. The calling code will know better how exactly to notify the user of the problem.
$endgroup$
– Roman Odaisky
May 31 at 0:07




5




5




$begingroup$
@IlmariKaronen That is almost certainly a failure in the specification. Such formatting would be obviously incorrect punctuation. The description doesn't contain any specific instructions on the case of a two item list and provides only an example of four items. Note that the description doesn't describe what to do in the case of empty or single item lists, either. The OP has extended the specification to handle edge cases that were left unspecified. Another valid approach would be to just throw an error for less than three items.
$endgroup$
– jpmc26
May 31 at 10:37





$begingroup$
@IlmariKaronen That is almost certainly a failure in the specification. Such formatting would be obviously incorrect punctuation. The description doesn't contain any specific instructions on the case of a two item list and provides only an example of four items. Note that the description doesn't describe what to do in the case of empty or single item lists, either. The OP has extended the specification to handle edge cases that were left unspecified. Another valid approach would be to just throw an error for less than three items.
$endgroup$
– jpmc26
May 31 at 10:37





2




2




$begingroup$
Don't return 'Your list is empty', throw an error!
$endgroup$
– Tvde1
Jun 2 at 10:23




$begingroup$
Don't return 'Your list is empty', throw an error!
$endgroup$
– Tvde1
Jun 2 at 10:23










6 Answers
6






active

oldest

votes


















9
















$begingroup$

You’ve got too many ()’s in this statement:



your_list_split1 = (', '.join((map(str,your_list[:-1]))))


You don’t need the parenthesis around the entire expression, nor for the argument inside of the join(...) function. You should also add a space after the comma, to be PEP-8 compliant:



your_list_split1 = ', '.join(map(str, your_list[:-1]))


I’m not sure if it was a requirement of the question or not, but generally with lists, you do not include a comma between the second last item and the word “and”. If that comma is not required by the assignment, then if you remove it, the items == 2 case is unnecessary, as the final else clause will properly handle 2 items. Edit: Or since the comma appears to be required, if it is acceptable for 2 items ('item1, and item2'), keep the comma in the else: and the items == 2 case is still unnecessary.



If you are learning Python 3, you should probably jump right to Python 3.7, and take advantage of f-strings, where you can put formatting codes for variables/expressions directly into the strings:



else:
return f"'your_list_split1, and your_list[-1]'"



Don’t intermix code and function definitions.



def list_concatenator(your_list):
# ... etc ...

your_list = [ ... ]
list_concatenator(your_list)



Avoid using global variable names as function argument names. In longer functions, the reader might get confused between whether a global variable is being referenced or not.




As it presently stands, your code does some work, gets a result, and then does nothing with it. You probably want to assign the returned value to a variable, or print it, or both.




You are calling str(...) alot throughout your function, to ensure that the item you are referencing in your list is a string which can be concatenated with other strings. You should instead just do it once, at the top of the function:



def list_concatenator(your_list):
your_list = list(map(str, your_list))
# remainder of the code, without the need for any str( ) calls.





share|improve this answer












$endgroup$










  • 7




    $begingroup$
    The Oxford comma is required in the assignment, as shown in the example output (whether we like it or not...).
    $endgroup$
    – Graipher
    May 30 at 15:18






  • 2




    $begingroup$
    And your_list = map(str, your_list) can be a problem, depending on what you want to do with it afterwards, since it is a generator-like object. So no [-1] to get the last element, no falsiness if it is empty, only being able to iterate over it once, etc. All of which you can remove by wrapping it with list(), of course.
    $endgroup$
    – Graipher
    May 30 at 15:22







  • 2




    $begingroup$
    generally with lists, you do not include a comma between the second last item and the word “and”. According to en.wikipedia.org/wiki/Serial_comma, "Opinions among writers and editors differ on whether to use the serial comma, and usage also differs somewhat between regional varieties of English. Generally (with few exceptions), British English does not make use of this comma, while on the other hand it is common and even mandatory in American English.[6] ... This practice is controversial and is known as the serial comma or Oxford comma. ..."
    $endgroup$
    – Solomon Ucko
    May 30 at 18:00






  • 3




    $begingroup$
    @Justin Actually that is the OP’s addition to the problem; it is not mentioned in the chapter 4 problem text (which is now included in the question post verbatim).
    $endgroup$
    – AJNeufeld
    May 30 at 20:41







  • 2




    $begingroup$
    @AJNeufeld - Yes, according to OP's stated question (with the addition), I meant.
    $endgroup$
    – Justin
    May 30 at 20:45


















13
















$begingroup$

Your code is well-built and covers everything stated in the task, but could be made much shorter by using the .format() function.




str.format() is one of the string formatting methods in Python 3, which
allows multiple substitutions and value formatting. This method lets
us concatenate elements within a string through positional formatting.




Your code can, therefore, be made shorter and more concise this way. Here is what your code might look like -



def list_concatenator(your_list):

if not your_list:
return "Your list is empty!"

elif len(your_list) == 1:
return str(your_list[0])

elif len(your_list) == 2:
return '0 and 1'.format(your_list[0], your_list[1])

else:
body = ", ".join(map(str, your_list[:-1]))
return '0, and 1'.format(body, your_list[-1])


I have used 0 and 1 so that positional arguments can be placed in the order you want them to be in, though it is not necessary to do so.



OR



Another way to format in Python 3 is to use f-strings.




The idea behind f-strings is to make string interpolation simpler. To create an f-string, prefix the string with the letter “ f ”. The string itself can be formatted in much the same way that you would with str.format(). f-strings provide a concise and convenient way to embed python expressions inside string literals for formatting.




Here's how your code would look like with f-strings (much shorter) -



def list_concetenator(your_list):

if not your_list:
return "Your list is empty!"

elif len(your_list) == 1:
return str(your_list[0])

elif len(your_list) == 2:
return f'your_list[0] and your_list[1]'

else:
body = ", ".join(map(str, a_list[:-1]))
return f'body, and your_list[-1]'


Here are some example outputs -



your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

print(list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]))
>>> item1, item2, 3, item4, item5, item6, 7, item8, and 9

print(list_concatenator(['item1', 'item2', 3]))
>>> item1, item2, and 3

print(list_concatenator(['item1', 3]))
>>> item1 and 3

print(list_concatenator(['item1']))
>>> item1

print(list_concatenator([]))
>>> Your list is empty!


The program also takes care of the Oxford comma, where lists with two items do not have commas (e.g. apples and bananas) but lists with more than two items are separated with commas (apples, bananas, and cakes). Here are some useful links that help us understand what Oxford commas really are and when they should be used -



  1. https://www.grammarly.com/blog/comma-before-and/


  2. https://en.wikipedia.org/wiki/Serial_comma


Overall, I believe formatting was the main problem in your code.




EDIT -



In the comments section above, @Ilmari Karonen correctly mentions that the usage of " ' " in the book is the book's way of writing string literals. Therefore, I have edited my answer to make this change (i.e. remove unnecessary quotes). But if you require these quotes, then you could always wrap the string in double quotes, like this - f"'your_list[0] and your_list[1]'" or this - "'0 and 1'".format(your_list[0], your_list[1]).



Another let-down in your code is the use of inconsistent parentheses here,



(', '.join((map(str,your_list[:-1]))))



which could just be written as -



', '.join(map(str,your_list[:-1])).



To remain concise and immaculate in writing programs, I suggest you have a look at PEP 8, which is Python's official style guide.



Hope this helps!






share|improve this answer












$endgroup$










  • 1




    $begingroup$
    forgot to comment earlier and say thanks, I did find your answer very useful too.
    $endgroup$
    – benb
    Jun 1 at 12:31










  • $begingroup$
    @benb - I'm glad my answer helped you. Just wondering why you unaccepted my answer :(
    $endgroup$
    – Justin
    Jun 3 at 13:04










  • $begingroup$
    Sorry about that, there's nothing wrong with your answer. I've actually started using f-strings because of your advice, thank you. It was difficult to pick ONE answer, and I decided on AJNeufelds because other beginners reading this would probably benefit from the extra things his answer covers (e.g., not to use global variable names as function names etc.).
    $endgroup$
    – benb
    Jun 4 at 4:08






  • 1




    $begingroup$
    @benb - No worries. Just so know, I've also provided a link to PEP 8, which is Python's official style guide. It should help you with formatting and style in every possible way.
    $endgroup$
    – Justin
    Jun 4 at 4:13


















9
















$begingroup$


  1. If you need to add '' then you should do this outside of the function. This can be fairly easy knowing the output is always a string.



    >>> print(repr(list_concatenator('a')))
    'a'


    By default the IDLE prompt does this automatically.



    >>> list_concatenator('a')
    'a'



  2. Rather than using len(your_list) == 0 you can use not your_list.



    if not your_list:
    return 'Your list is empty'


  3. You can use str.join to join the rest of your lists.


def list_concatenator(your_list, comma=', ', conjunction=' and '):
if not your_list:
return 'Your list is empty'

your_list = [str(i) for i in your_list]
if len(your_list) > 1:
your_list[:-1] = [comma.join(your_list[:-1])]
return conjunction.join(your_list)

>>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
'item1, item2, 3, item4, item5, item6, 7, item8 and 9'
>>> list_concatenator('abcde', conjunction=' or ')
'a, b, c, d or e'
>>> list_concatenator('abcde', conjunction=', or ')
'a, b, c, d, or e'
>>> list_concatenator('ab')
'a and b'
>>> list_concatenator('a')
'a'



It should be noted that the challenge says to seperate each value with a ', ', and so you could simplify this by mutating the last value with the conjunction, and just use one str.join.



def list_concatenator(your_list, comma=', ', conjunction='and'):
if not your_list:
return 'Your list is empty'

your_list = [str(i) for i in your_list]
if len(your_list) > 1:
your_list[-1] = conjunction + ' ' + your_list[-1]
return comma.join(your_list)

>>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
'item1, item2, 3, item4, item5, item6, 7, item8, and 9'
>>> list_concatenator('abcde', conjunction='or')
'a, b, c, d, or e'
>>> list_concatenator('ab')
'a, and b'
>>> list_concatenator('a')
'a'





share|improve this answer












$endgroup$










  • 1




    $begingroup$
    Posting on behalf of a_faulty_star. a_faulty_star: P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!
    $endgroup$
    – benb
    May 31 at 8:18






  • 1




    $begingroup$
    @benb It was in your original code. You should be able to see how to remove them if you need to.
    $endgroup$
    – Peilonrayz
    May 31 at 8:22






  • 2




    $begingroup$
    In my original code the output looked like 'item1, item2' etc., with the whole string having ' ' around it. What a_faulty_star is pointing out is in the above code the output is 'item1', 'item2' two etc., with each item having it's own quotes. As you said, you can fix it by taking out the double quotes "" in your_list = [f"'i'" for i in your_list].
    $endgroup$
    – benb
    May 31 at 8:41






  • 2




    $begingroup$
    Ah, I misread your ' and ' as "' and '". I've changed it now.
    $endgroup$
    – Peilonrayz
    May 31 at 9:01


















5
















$begingroup$

I used the following function for achieving the task. I am new here, so please feel free to comment anything you feel is wrong!



In the function, firstly, I check if the given list is empty or not.



If it is, then I return an empty string.



Otherwise, I first store the length of string in a variable. Then, I use list comprehension to convert all the elements in the list to string format, because some of them may be non-string and cause an error while using join function. Then, I join the strings in the list, separated by a comma and space, by using the join function on all elements of the list except the last. Then, I add an 'and' if the list has three or more elements. I have added the Oxford comma and a space before 'and' because the question has mentioned it.



Here is the function:



>>> def list_concatenator(your_list):
if not your_list:
return ''
your_list = [str(i) for i in your_list]
p = len(your_list)
return ', '.join(your_list[:-1]) + (',' if p>2 else '') + (' and ' if p>1 else '') + your_list[-1]


Here are some outputs:



>>> li = []
>>> print(list_concatenator(li))


>>> li2 = ['apples']
>>> print(list_concatenator(li2))
apples

>>> li3 = ['apples', 'bananas']
>>> print(list_concatenator(li3))
apples and bananas

>>> li4 = ['apples', 'bananas', 'tofu', 'cats']
>>> print(list_concatenator(li4))
apples, bananas, tofu, and cats

>>> li5 = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]
>>> print(list_concatenator(li5))
item1, item2, 3, item4, item5, item6, 7, item8, and 9


P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!






share|improve this answer












$endgroup$










  • 2




    $begingroup$
    I think this is a great solution. I will leave @AJNeufeld comment as the answer as I think it provides a lot of useful information for a beginner, but your solution seems to do everything required while also being very concise. Thanks.
    $endgroup$
    – benb
    May 31 at 8:21






  • 1




    $begingroup$
    I have left the code to work as close to the original code as possible. For ease of programming I changed from the oxford comma to what the spec defines. But the function works the same otherwise.
    $endgroup$
    – Peilonrayz
    May 31 at 8:25






  • 1




    $begingroup$
    @a_faulty_star - You have not implemented the Oxford comma in your answer. An Oxford comma is where lists with two items do not have commas but lists with more than two items are separated with commas. Here is the link - en.wikipedia.org/wiki/Serial_comma. Therefore, if you are using the Oxford comma, then your third output should be - apples and bananas.
    $endgroup$
    – Justin
    May 31 at 12:38






  • 3




    $begingroup$
    @a_faulty_star - No worries. Your answer is pretty close to a code review and you have already received 3 upvotes, which is amazing for a first attempt. As benb said, your solution is very concise, so it did help him. Kudos for writing your first answer on Code Review!
    $endgroup$
    – Justin
    May 31 at 13:21







  • 2




    $begingroup$
    Thank you @Justin. You and benb are too kind :')
    $endgroup$
    – a_faulty_star
    May 31 at 13:55


















3
















$begingroup$

Here are a few mostly stylistic points.



 def list_concatenator(your_list):


"list_concatenator" is a poor choice for a function name. I'd rather expect "concatenator" to be a class that provides concatenation. A function name is, more commonly, a verb, that tells what the function does (e.g. sort) or a noun describing what the function returns (e.g. sqrt). Besides, "concatenate a list" is a very vague description of the task at hand. Therefore I'd suggest to name your function like "join_with_serial_comma" or "oxford_comma_concat" or even "oxfordize" ;)



"your_list" is bad too (who's this "you" exactly?). It's just some list, so name it "some_list" or "a_list" or "lst". Moreover, since you're only using len and [] in your code, there's no reason to restrict your function to lists specifically, just make it accept any sequence and name your argument like "sequence" or "seq"



 items = len(your_list)


Again, poor variable naming. items is what the list contains (cf. dict.items), what you mean here is length, size, number_of_items and so on.



 if items == 0:
return 'Your list is empty'


An empty list is an exceptional situation for your function, and you can't and shouldn't return any value in this case. Much better option would be to raise an exception (ValueError would be a good choice), better yet, just remove this condition, the rest of the code is going to break anyways if the argument is empty (or not a sequence at all, for that matter). Ask forgiveness, not permission.



 elif items == 1:
return "'" + str(your_list[0]) + "'"


If the previous condition ends with return or raise, there's no need for elif, just if would be more readable.



 elif items == 2:
return "'" + str(your_list[0]) + ' and ' + str(your_list[1]) + "'"


As said in other posts, format or f-strings are usually more readable than concatenation.



 else:
your_list_split1 = (', '.join((map(str,your_list[:-1]))))
return "'" + your_list_split1 + ', and ' + str(your_list[-1]) + "'"


Yet again, your_list_split1 is a weird variable name, and doesn't reflect what the variable actually contains.



Since you always return from other branches, you can remove else here and reduce the indentation.



Comprehensions are usually more readable in python than map:



 head = ', '.join(str(item) for item in sequence[:-1])


A more "pythonic" alternative to -1 indexing would be an unpacking assignment:



 *head, tail = seq
head_joined = ', '.join(str(p) for p in head)
return f'head_joined, and tail'


Hope this helps.






share|improve this answer












$endgroup$






















    2
















    $begingroup$

    Slicing the list would allow you to get all except the last element. Testing the list length will indicate what needs to go before the final element.



    if len(your_list) > 0:
    if len(your_list) > 2: ander = ',' # if passive comma needed
    if len(your_list) > 1: ander += ' and '
    ', '.join(your_list[0:-1]) + ander + thelist[-1]





    share|improve this answer










    $endgroup$
















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "196"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );














      draft saved

      draft discarded
















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f221318%2fcomma-code-ch-4-automate-the-boring-stuff%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown


























      6 Answers
      6






      active

      oldest

      votes








      6 Answers
      6






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      9
















      $begingroup$

      You’ve got too many ()’s in this statement:



      your_list_split1 = (', '.join((map(str,your_list[:-1]))))


      You don’t need the parenthesis around the entire expression, nor for the argument inside of the join(...) function. You should also add a space after the comma, to be PEP-8 compliant:



      your_list_split1 = ', '.join(map(str, your_list[:-1]))


      I’m not sure if it was a requirement of the question or not, but generally with lists, you do not include a comma between the second last item and the word “and”. If that comma is not required by the assignment, then if you remove it, the items == 2 case is unnecessary, as the final else clause will properly handle 2 items. Edit: Or since the comma appears to be required, if it is acceptable for 2 items ('item1, and item2'), keep the comma in the else: and the items == 2 case is still unnecessary.



      If you are learning Python 3, you should probably jump right to Python 3.7, and take advantage of f-strings, where you can put formatting codes for variables/expressions directly into the strings:



      else:
      return f"'your_list_split1, and your_list[-1]'"



      Don’t intermix code and function definitions.



      def list_concatenator(your_list):
      # ... etc ...

      your_list = [ ... ]
      list_concatenator(your_list)



      Avoid using global variable names as function argument names. In longer functions, the reader might get confused between whether a global variable is being referenced or not.




      As it presently stands, your code does some work, gets a result, and then does nothing with it. You probably want to assign the returned value to a variable, or print it, or both.




      You are calling str(...) alot throughout your function, to ensure that the item you are referencing in your list is a string which can be concatenated with other strings. You should instead just do it once, at the top of the function:



      def list_concatenator(your_list):
      your_list = list(map(str, your_list))
      # remainder of the code, without the need for any str( ) calls.





      share|improve this answer












      $endgroup$










      • 7




        $begingroup$
        The Oxford comma is required in the assignment, as shown in the example output (whether we like it or not...).
        $endgroup$
        – Graipher
        May 30 at 15:18






      • 2




        $begingroup$
        And your_list = map(str, your_list) can be a problem, depending on what you want to do with it afterwards, since it is a generator-like object. So no [-1] to get the last element, no falsiness if it is empty, only being able to iterate over it once, etc. All of which you can remove by wrapping it with list(), of course.
        $endgroup$
        – Graipher
        May 30 at 15:22







      • 2




        $begingroup$
        generally with lists, you do not include a comma between the second last item and the word “and”. According to en.wikipedia.org/wiki/Serial_comma, "Opinions among writers and editors differ on whether to use the serial comma, and usage also differs somewhat between regional varieties of English. Generally (with few exceptions), British English does not make use of this comma, while on the other hand it is common and even mandatory in American English.[6] ... This practice is controversial and is known as the serial comma or Oxford comma. ..."
        $endgroup$
        – Solomon Ucko
        May 30 at 18:00






      • 3




        $begingroup$
        @Justin Actually that is the OP’s addition to the problem; it is not mentioned in the chapter 4 problem text (which is now included in the question post verbatim).
        $endgroup$
        – AJNeufeld
        May 30 at 20:41







      • 2




        $begingroup$
        @AJNeufeld - Yes, according to OP's stated question (with the addition), I meant.
        $endgroup$
        – Justin
        May 30 at 20:45















      9
















      $begingroup$

      You’ve got too many ()’s in this statement:



      your_list_split1 = (', '.join((map(str,your_list[:-1]))))


      You don’t need the parenthesis around the entire expression, nor for the argument inside of the join(...) function. You should also add a space after the comma, to be PEP-8 compliant:



      your_list_split1 = ', '.join(map(str, your_list[:-1]))


      I’m not sure if it was a requirement of the question or not, but generally with lists, you do not include a comma between the second last item and the word “and”. If that comma is not required by the assignment, then if you remove it, the items == 2 case is unnecessary, as the final else clause will properly handle 2 items. Edit: Or since the comma appears to be required, if it is acceptable for 2 items ('item1, and item2'), keep the comma in the else: and the items == 2 case is still unnecessary.



      If you are learning Python 3, you should probably jump right to Python 3.7, and take advantage of f-strings, where you can put formatting codes for variables/expressions directly into the strings:



      else:
      return f"'your_list_split1, and your_list[-1]'"



      Don’t intermix code and function definitions.



      def list_concatenator(your_list):
      # ... etc ...

      your_list = [ ... ]
      list_concatenator(your_list)



      Avoid using global variable names as function argument names. In longer functions, the reader might get confused between whether a global variable is being referenced or not.




      As it presently stands, your code does some work, gets a result, and then does nothing with it. You probably want to assign the returned value to a variable, or print it, or both.




      You are calling str(...) alot throughout your function, to ensure that the item you are referencing in your list is a string which can be concatenated with other strings. You should instead just do it once, at the top of the function:



      def list_concatenator(your_list):
      your_list = list(map(str, your_list))
      # remainder of the code, without the need for any str( ) calls.





      share|improve this answer












      $endgroup$










      • 7




        $begingroup$
        The Oxford comma is required in the assignment, as shown in the example output (whether we like it or not...).
        $endgroup$
        – Graipher
        May 30 at 15:18






      • 2




        $begingroup$
        And your_list = map(str, your_list) can be a problem, depending on what you want to do with it afterwards, since it is a generator-like object. So no [-1] to get the last element, no falsiness if it is empty, only being able to iterate over it once, etc. All of which you can remove by wrapping it with list(), of course.
        $endgroup$
        – Graipher
        May 30 at 15:22







      • 2




        $begingroup$
        generally with lists, you do not include a comma between the second last item and the word “and”. According to en.wikipedia.org/wiki/Serial_comma, "Opinions among writers and editors differ on whether to use the serial comma, and usage also differs somewhat between regional varieties of English. Generally (with few exceptions), British English does not make use of this comma, while on the other hand it is common and even mandatory in American English.[6] ... This practice is controversial and is known as the serial comma or Oxford comma. ..."
        $endgroup$
        – Solomon Ucko
        May 30 at 18:00






      • 3




        $begingroup$
        @Justin Actually that is the OP’s addition to the problem; it is not mentioned in the chapter 4 problem text (which is now included in the question post verbatim).
        $endgroup$
        – AJNeufeld
        May 30 at 20:41







      • 2




        $begingroup$
        @AJNeufeld - Yes, according to OP's stated question (with the addition), I meant.
        $endgroup$
        – Justin
        May 30 at 20:45













      9














      9










      9







      $begingroup$

      You’ve got too many ()’s in this statement:



      your_list_split1 = (', '.join((map(str,your_list[:-1]))))


      You don’t need the parenthesis around the entire expression, nor for the argument inside of the join(...) function. You should also add a space after the comma, to be PEP-8 compliant:



      your_list_split1 = ', '.join(map(str, your_list[:-1]))


      I’m not sure if it was a requirement of the question or not, but generally with lists, you do not include a comma between the second last item and the word “and”. If that comma is not required by the assignment, then if you remove it, the items == 2 case is unnecessary, as the final else clause will properly handle 2 items. Edit: Or since the comma appears to be required, if it is acceptable for 2 items ('item1, and item2'), keep the comma in the else: and the items == 2 case is still unnecessary.



      If you are learning Python 3, you should probably jump right to Python 3.7, and take advantage of f-strings, where you can put formatting codes for variables/expressions directly into the strings:



      else:
      return f"'your_list_split1, and your_list[-1]'"



      Don’t intermix code and function definitions.



      def list_concatenator(your_list):
      # ... etc ...

      your_list = [ ... ]
      list_concatenator(your_list)



      Avoid using global variable names as function argument names. In longer functions, the reader might get confused between whether a global variable is being referenced or not.




      As it presently stands, your code does some work, gets a result, and then does nothing with it. You probably want to assign the returned value to a variable, or print it, or both.




      You are calling str(...) alot throughout your function, to ensure that the item you are referencing in your list is a string which can be concatenated with other strings. You should instead just do it once, at the top of the function:



      def list_concatenator(your_list):
      your_list = list(map(str, your_list))
      # remainder of the code, without the need for any str( ) calls.





      share|improve this answer












      $endgroup$



      You’ve got too many ()’s in this statement:



      your_list_split1 = (', '.join((map(str,your_list[:-1]))))


      You don’t need the parenthesis around the entire expression, nor for the argument inside of the join(...) function. You should also add a space after the comma, to be PEP-8 compliant:



      your_list_split1 = ', '.join(map(str, your_list[:-1]))


      I’m not sure if it was a requirement of the question or not, but generally with lists, you do not include a comma between the second last item and the word “and”. If that comma is not required by the assignment, then if you remove it, the items == 2 case is unnecessary, as the final else clause will properly handle 2 items. Edit: Or since the comma appears to be required, if it is acceptable for 2 items ('item1, and item2'), keep the comma in the else: and the items == 2 case is still unnecessary.



      If you are learning Python 3, you should probably jump right to Python 3.7, and take advantage of f-strings, where you can put formatting codes for variables/expressions directly into the strings:



      else:
      return f"'your_list_split1, and your_list[-1]'"



      Don’t intermix code and function definitions.



      def list_concatenator(your_list):
      # ... etc ...

      your_list = [ ... ]
      list_concatenator(your_list)



      Avoid using global variable names as function argument names. In longer functions, the reader might get confused between whether a global variable is being referenced or not.




      As it presently stands, your code does some work, gets a result, and then does nothing with it. You probably want to assign the returned value to a variable, or print it, or both.




      You are calling str(...) alot throughout your function, to ensure that the item you are referencing in your list is a string which can be concatenated with other strings. You should instead just do it once, at the top of the function:



      def list_concatenator(your_list):
      your_list = list(map(str, your_list))
      # remainder of the code, without the need for any str( ) calls.






      share|improve this answer















      share|improve this answer




      share|improve this answer








      edited May 30 at 15:38

























      answered May 30 at 4:50









      AJNeufeldAJNeufeld

      13.2k1 gold badge13 silver badges40 bronze badges




      13.2k1 gold badge13 silver badges40 bronze badges










      • 7




        $begingroup$
        The Oxford comma is required in the assignment, as shown in the example output (whether we like it or not...).
        $endgroup$
        – Graipher
        May 30 at 15:18






      • 2




        $begingroup$
        And your_list = map(str, your_list) can be a problem, depending on what you want to do with it afterwards, since it is a generator-like object. So no [-1] to get the last element, no falsiness if it is empty, only being able to iterate over it once, etc. All of which you can remove by wrapping it with list(), of course.
        $endgroup$
        – Graipher
        May 30 at 15:22







      • 2




        $begingroup$
        generally with lists, you do not include a comma between the second last item and the word “and”. According to en.wikipedia.org/wiki/Serial_comma, "Opinions among writers and editors differ on whether to use the serial comma, and usage also differs somewhat between regional varieties of English. Generally (with few exceptions), British English does not make use of this comma, while on the other hand it is common and even mandatory in American English.[6] ... This practice is controversial and is known as the serial comma or Oxford comma. ..."
        $endgroup$
        – Solomon Ucko
        May 30 at 18:00






      • 3




        $begingroup$
        @Justin Actually that is the OP’s addition to the problem; it is not mentioned in the chapter 4 problem text (which is now included in the question post verbatim).
        $endgroup$
        – AJNeufeld
        May 30 at 20:41







      • 2




        $begingroup$
        @AJNeufeld - Yes, according to OP's stated question (with the addition), I meant.
        $endgroup$
        – Justin
        May 30 at 20:45












      • 7




        $begingroup$
        The Oxford comma is required in the assignment, as shown in the example output (whether we like it or not...).
        $endgroup$
        – Graipher
        May 30 at 15:18






      • 2




        $begingroup$
        And your_list = map(str, your_list) can be a problem, depending on what you want to do with it afterwards, since it is a generator-like object. So no [-1] to get the last element, no falsiness if it is empty, only being able to iterate over it once, etc. All of which you can remove by wrapping it with list(), of course.
        $endgroup$
        – Graipher
        May 30 at 15:22







      • 2




        $begingroup$
        generally with lists, you do not include a comma between the second last item and the word “and”. According to en.wikipedia.org/wiki/Serial_comma, "Opinions among writers and editors differ on whether to use the serial comma, and usage also differs somewhat between regional varieties of English. Generally (with few exceptions), British English does not make use of this comma, while on the other hand it is common and even mandatory in American English.[6] ... This practice is controversial and is known as the serial comma or Oxford comma. ..."
        $endgroup$
        – Solomon Ucko
        May 30 at 18:00






      • 3




        $begingroup$
        @Justin Actually that is the OP’s addition to the problem; it is not mentioned in the chapter 4 problem text (which is now included in the question post verbatim).
        $endgroup$
        – AJNeufeld
        May 30 at 20:41







      • 2




        $begingroup$
        @AJNeufeld - Yes, according to OP's stated question (with the addition), I meant.
        $endgroup$
        – Justin
        May 30 at 20:45







      7




      7




      $begingroup$
      The Oxford comma is required in the assignment, as shown in the example output (whether we like it or not...).
      $endgroup$
      – Graipher
      May 30 at 15:18




      $begingroup$
      The Oxford comma is required in the assignment, as shown in the example output (whether we like it or not...).
      $endgroup$
      – Graipher
      May 30 at 15:18




      2




      2




      $begingroup$
      And your_list = map(str, your_list) can be a problem, depending on what you want to do with it afterwards, since it is a generator-like object. So no [-1] to get the last element, no falsiness if it is empty, only being able to iterate over it once, etc. All of which you can remove by wrapping it with list(), of course.
      $endgroup$
      – Graipher
      May 30 at 15:22





      $begingroup$
      And your_list = map(str, your_list) can be a problem, depending on what you want to do with it afterwards, since it is a generator-like object. So no [-1] to get the last element, no falsiness if it is empty, only being able to iterate over it once, etc. All of which you can remove by wrapping it with list(), of course.
      $endgroup$
      – Graipher
      May 30 at 15:22





      2




      2




      $begingroup$
      generally with lists, you do not include a comma between the second last item and the word “and”. According to en.wikipedia.org/wiki/Serial_comma, "Opinions among writers and editors differ on whether to use the serial comma, and usage also differs somewhat between regional varieties of English. Generally (with few exceptions), British English does not make use of this comma, while on the other hand it is common and even mandatory in American English.[6] ... This practice is controversial and is known as the serial comma or Oxford comma. ..."
      $endgroup$
      – Solomon Ucko
      May 30 at 18:00




      $begingroup$
      generally with lists, you do not include a comma between the second last item and the word “and”. According to en.wikipedia.org/wiki/Serial_comma, "Opinions among writers and editors differ on whether to use the serial comma, and usage also differs somewhat between regional varieties of English. Generally (with few exceptions), British English does not make use of this comma, while on the other hand it is common and even mandatory in American English.[6] ... This practice is controversial and is known as the serial comma or Oxford comma. ..."
      $endgroup$
      – Solomon Ucko
      May 30 at 18:00




      3




      3




      $begingroup$
      @Justin Actually that is the OP’s addition to the problem; it is not mentioned in the chapter 4 problem text (which is now included in the question post verbatim).
      $endgroup$
      – AJNeufeld
      May 30 at 20:41





      $begingroup$
      @Justin Actually that is the OP’s addition to the problem; it is not mentioned in the chapter 4 problem text (which is now included in the question post verbatim).
      $endgroup$
      – AJNeufeld
      May 30 at 20:41





      2




      2




      $begingroup$
      @AJNeufeld - Yes, according to OP's stated question (with the addition), I meant.
      $endgroup$
      – Justin
      May 30 at 20:45




      $begingroup$
      @AJNeufeld - Yes, according to OP's stated question (with the addition), I meant.
      $endgroup$
      – Justin
      May 30 at 20:45













      13
















      $begingroup$

      Your code is well-built and covers everything stated in the task, but could be made much shorter by using the .format() function.




      str.format() is one of the string formatting methods in Python 3, which
      allows multiple substitutions and value formatting. This method lets
      us concatenate elements within a string through positional formatting.




      Your code can, therefore, be made shorter and more concise this way. Here is what your code might look like -



      def list_concatenator(your_list):

      if not your_list:
      return "Your list is empty!"

      elif len(your_list) == 1:
      return str(your_list[0])

      elif len(your_list) == 2:
      return '0 and 1'.format(your_list[0], your_list[1])

      else:
      body = ", ".join(map(str, your_list[:-1]))
      return '0, and 1'.format(body, your_list[-1])


      I have used 0 and 1 so that positional arguments can be placed in the order you want them to be in, though it is not necessary to do so.



      OR



      Another way to format in Python 3 is to use f-strings.




      The idea behind f-strings is to make string interpolation simpler. To create an f-string, prefix the string with the letter “ f ”. The string itself can be formatted in much the same way that you would with str.format(). f-strings provide a concise and convenient way to embed python expressions inside string literals for formatting.




      Here's how your code would look like with f-strings (much shorter) -



      def list_concetenator(your_list):

      if not your_list:
      return "Your list is empty!"

      elif len(your_list) == 1:
      return str(your_list[0])

      elif len(your_list) == 2:
      return f'your_list[0] and your_list[1]'

      else:
      body = ", ".join(map(str, a_list[:-1]))
      return f'body, and your_list[-1]'


      Here are some example outputs -



      your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

      print(list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]))
      >>> item1, item2, 3, item4, item5, item6, 7, item8, and 9

      print(list_concatenator(['item1', 'item2', 3]))
      >>> item1, item2, and 3

      print(list_concatenator(['item1', 3]))
      >>> item1 and 3

      print(list_concatenator(['item1']))
      >>> item1

      print(list_concatenator([]))
      >>> Your list is empty!


      The program also takes care of the Oxford comma, where lists with two items do not have commas (e.g. apples and bananas) but lists with more than two items are separated with commas (apples, bananas, and cakes). Here are some useful links that help us understand what Oxford commas really are and when they should be used -



      1. https://www.grammarly.com/blog/comma-before-and/


      2. https://en.wikipedia.org/wiki/Serial_comma


      Overall, I believe formatting was the main problem in your code.




      EDIT -



      In the comments section above, @Ilmari Karonen correctly mentions that the usage of " ' " in the book is the book's way of writing string literals. Therefore, I have edited my answer to make this change (i.e. remove unnecessary quotes). But if you require these quotes, then you could always wrap the string in double quotes, like this - f"'your_list[0] and your_list[1]'" or this - "'0 and 1'".format(your_list[0], your_list[1]).



      Another let-down in your code is the use of inconsistent parentheses here,



      (', '.join((map(str,your_list[:-1]))))



      which could just be written as -



      ', '.join(map(str,your_list[:-1])).



      To remain concise and immaculate in writing programs, I suggest you have a look at PEP 8, which is Python's official style guide.



      Hope this helps!






      share|improve this answer












      $endgroup$










      • 1




        $begingroup$
        forgot to comment earlier and say thanks, I did find your answer very useful too.
        $endgroup$
        – benb
        Jun 1 at 12:31










      • $begingroup$
        @benb - I'm glad my answer helped you. Just wondering why you unaccepted my answer :(
        $endgroup$
        – Justin
        Jun 3 at 13:04










      • $begingroup$
        Sorry about that, there's nothing wrong with your answer. I've actually started using f-strings because of your advice, thank you. It was difficult to pick ONE answer, and I decided on AJNeufelds because other beginners reading this would probably benefit from the extra things his answer covers (e.g., not to use global variable names as function names etc.).
        $endgroup$
        – benb
        Jun 4 at 4:08






      • 1




        $begingroup$
        @benb - No worries. Just so know, I've also provided a link to PEP 8, which is Python's official style guide. It should help you with formatting and style in every possible way.
        $endgroup$
        – Justin
        Jun 4 at 4:13















      13
















      $begingroup$

      Your code is well-built and covers everything stated in the task, but could be made much shorter by using the .format() function.




      str.format() is one of the string formatting methods in Python 3, which
      allows multiple substitutions and value formatting. This method lets
      us concatenate elements within a string through positional formatting.




      Your code can, therefore, be made shorter and more concise this way. Here is what your code might look like -



      def list_concatenator(your_list):

      if not your_list:
      return "Your list is empty!"

      elif len(your_list) == 1:
      return str(your_list[0])

      elif len(your_list) == 2:
      return '0 and 1'.format(your_list[0], your_list[1])

      else:
      body = ", ".join(map(str, your_list[:-1]))
      return '0, and 1'.format(body, your_list[-1])


      I have used 0 and 1 so that positional arguments can be placed in the order you want them to be in, though it is not necessary to do so.



      OR



      Another way to format in Python 3 is to use f-strings.




      The idea behind f-strings is to make string interpolation simpler. To create an f-string, prefix the string with the letter “ f ”. The string itself can be formatted in much the same way that you would with str.format(). f-strings provide a concise and convenient way to embed python expressions inside string literals for formatting.




      Here's how your code would look like with f-strings (much shorter) -



      def list_concetenator(your_list):

      if not your_list:
      return "Your list is empty!"

      elif len(your_list) == 1:
      return str(your_list[0])

      elif len(your_list) == 2:
      return f'your_list[0] and your_list[1]'

      else:
      body = ", ".join(map(str, a_list[:-1]))
      return f'body, and your_list[-1]'


      Here are some example outputs -



      your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

      print(list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]))
      >>> item1, item2, 3, item4, item5, item6, 7, item8, and 9

      print(list_concatenator(['item1', 'item2', 3]))
      >>> item1, item2, and 3

      print(list_concatenator(['item1', 3]))
      >>> item1 and 3

      print(list_concatenator(['item1']))
      >>> item1

      print(list_concatenator([]))
      >>> Your list is empty!


      The program also takes care of the Oxford comma, where lists with two items do not have commas (e.g. apples and bananas) but lists with more than two items are separated with commas (apples, bananas, and cakes). Here are some useful links that help us understand what Oxford commas really are and when they should be used -



      1. https://www.grammarly.com/blog/comma-before-and/


      2. https://en.wikipedia.org/wiki/Serial_comma


      Overall, I believe formatting was the main problem in your code.




      EDIT -



      In the comments section above, @Ilmari Karonen correctly mentions that the usage of " ' " in the book is the book's way of writing string literals. Therefore, I have edited my answer to make this change (i.e. remove unnecessary quotes). But if you require these quotes, then you could always wrap the string in double quotes, like this - f"'your_list[0] and your_list[1]'" or this - "'0 and 1'".format(your_list[0], your_list[1]).



      Another let-down in your code is the use of inconsistent parentheses here,



      (', '.join((map(str,your_list[:-1]))))



      which could just be written as -



      ', '.join(map(str,your_list[:-1])).



      To remain concise and immaculate in writing programs, I suggest you have a look at PEP 8, which is Python's official style guide.



      Hope this helps!






      share|improve this answer












      $endgroup$










      • 1




        $begingroup$
        forgot to comment earlier and say thanks, I did find your answer very useful too.
        $endgroup$
        – benb
        Jun 1 at 12:31










      • $begingroup$
        @benb - I'm glad my answer helped you. Just wondering why you unaccepted my answer :(
        $endgroup$
        – Justin
        Jun 3 at 13:04










      • $begingroup$
        Sorry about that, there's nothing wrong with your answer. I've actually started using f-strings because of your advice, thank you. It was difficult to pick ONE answer, and I decided on AJNeufelds because other beginners reading this would probably benefit from the extra things his answer covers (e.g., not to use global variable names as function names etc.).
        $endgroup$
        – benb
        Jun 4 at 4:08






      • 1




        $begingroup$
        @benb - No worries. Just so know, I've also provided a link to PEP 8, which is Python's official style guide. It should help you with formatting and style in every possible way.
        $endgroup$
        – Justin
        Jun 4 at 4:13













      13














      13










      13







      $begingroup$

      Your code is well-built and covers everything stated in the task, but could be made much shorter by using the .format() function.




      str.format() is one of the string formatting methods in Python 3, which
      allows multiple substitutions and value formatting. This method lets
      us concatenate elements within a string through positional formatting.




      Your code can, therefore, be made shorter and more concise this way. Here is what your code might look like -



      def list_concatenator(your_list):

      if not your_list:
      return "Your list is empty!"

      elif len(your_list) == 1:
      return str(your_list[0])

      elif len(your_list) == 2:
      return '0 and 1'.format(your_list[0], your_list[1])

      else:
      body = ", ".join(map(str, your_list[:-1]))
      return '0, and 1'.format(body, your_list[-1])


      I have used 0 and 1 so that positional arguments can be placed in the order you want them to be in, though it is not necessary to do so.



      OR



      Another way to format in Python 3 is to use f-strings.




      The idea behind f-strings is to make string interpolation simpler. To create an f-string, prefix the string with the letter “ f ”. The string itself can be formatted in much the same way that you would with str.format(). f-strings provide a concise and convenient way to embed python expressions inside string literals for formatting.




      Here's how your code would look like with f-strings (much shorter) -



      def list_concetenator(your_list):

      if not your_list:
      return "Your list is empty!"

      elif len(your_list) == 1:
      return str(your_list[0])

      elif len(your_list) == 2:
      return f'your_list[0] and your_list[1]'

      else:
      body = ", ".join(map(str, a_list[:-1]))
      return f'body, and your_list[-1]'


      Here are some example outputs -



      your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

      print(list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]))
      >>> item1, item2, 3, item4, item5, item6, 7, item8, and 9

      print(list_concatenator(['item1', 'item2', 3]))
      >>> item1, item2, and 3

      print(list_concatenator(['item1', 3]))
      >>> item1 and 3

      print(list_concatenator(['item1']))
      >>> item1

      print(list_concatenator([]))
      >>> Your list is empty!


      The program also takes care of the Oxford comma, where lists with two items do not have commas (e.g. apples and bananas) but lists with more than two items are separated with commas (apples, bananas, and cakes). Here are some useful links that help us understand what Oxford commas really are and when they should be used -



      1. https://www.grammarly.com/blog/comma-before-and/


      2. https://en.wikipedia.org/wiki/Serial_comma


      Overall, I believe formatting was the main problem in your code.




      EDIT -



      In the comments section above, @Ilmari Karonen correctly mentions that the usage of " ' " in the book is the book's way of writing string literals. Therefore, I have edited my answer to make this change (i.e. remove unnecessary quotes). But if you require these quotes, then you could always wrap the string in double quotes, like this - f"'your_list[0] and your_list[1]'" or this - "'0 and 1'".format(your_list[0], your_list[1]).



      Another let-down in your code is the use of inconsistent parentheses here,



      (', '.join((map(str,your_list[:-1]))))



      which could just be written as -



      ', '.join(map(str,your_list[:-1])).



      To remain concise and immaculate in writing programs, I suggest you have a look at PEP 8, which is Python's official style guide.



      Hope this helps!






      share|improve this answer












      $endgroup$



      Your code is well-built and covers everything stated in the task, but could be made much shorter by using the .format() function.




      str.format() is one of the string formatting methods in Python 3, which
      allows multiple substitutions and value formatting. This method lets
      us concatenate elements within a string through positional formatting.




      Your code can, therefore, be made shorter and more concise this way. Here is what your code might look like -



      def list_concatenator(your_list):

      if not your_list:
      return "Your list is empty!"

      elif len(your_list) == 1:
      return str(your_list[0])

      elif len(your_list) == 2:
      return '0 and 1'.format(your_list[0], your_list[1])

      else:
      body = ", ".join(map(str, your_list[:-1]))
      return '0, and 1'.format(body, your_list[-1])


      I have used 0 and 1 so that positional arguments can be placed in the order you want them to be in, though it is not necessary to do so.



      OR



      Another way to format in Python 3 is to use f-strings.




      The idea behind f-strings is to make string interpolation simpler. To create an f-string, prefix the string with the letter “ f ”. The string itself can be formatted in much the same way that you would with str.format(). f-strings provide a concise and convenient way to embed python expressions inside string literals for formatting.




      Here's how your code would look like with f-strings (much shorter) -



      def list_concetenator(your_list):

      if not your_list:
      return "Your list is empty!"

      elif len(your_list) == 1:
      return str(your_list[0])

      elif len(your_list) == 2:
      return f'your_list[0] and your_list[1]'

      else:
      body = ", ".join(map(str, a_list[:-1]))
      return f'body, and your_list[-1]'


      Here are some example outputs -



      your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

      print(list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]))
      >>> item1, item2, 3, item4, item5, item6, 7, item8, and 9

      print(list_concatenator(['item1', 'item2', 3]))
      >>> item1, item2, and 3

      print(list_concatenator(['item1', 3]))
      >>> item1 and 3

      print(list_concatenator(['item1']))
      >>> item1

      print(list_concatenator([]))
      >>> Your list is empty!


      The program also takes care of the Oxford comma, where lists with two items do not have commas (e.g. apples and bananas) but lists with more than two items are separated with commas (apples, bananas, and cakes). Here are some useful links that help us understand what Oxford commas really are and when they should be used -



      1. https://www.grammarly.com/blog/comma-before-and/


      2. https://en.wikipedia.org/wiki/Serial_comma


      Overall, I believe formatting was the main problem in your code.




      EDIT -



      In the comments section above, @Ilmari Karonen correctly mentions that the usage of " ' " in the book is the book's way of writing string literals. Therefore, I have edited my answer to make this change (i.e. remove unnecessary quotes). But if you require these quotes, then you could always wrap the string in double quotes, like this - f"'your_list[0] and your_list[1]'" or this - "'0 and 1'".format(your_list[0], your_list[1]).



      Another let-down in your code is the use of inconsistent parentheses here,



      (', '.join((map(str,your_list[:-1]))))



      which could just be written as -



      ', '.join(map(str,your_list[:-1])).



      To remain concise and immaculate in writing programs, I suggest you have a look at PEP 8, which is Python's official style guide.



      Hope this helps!







      share|improve this answer















      share|improve this answer




      share|improve this answer








      edited Jun 3 at 13:06

























      answered May 30 at 4:53









      JustinJustin

      1,4906 silver badges30 bronze badges




      1,4906 silver badges30 bronze badges










      • 1




        $begingroup$
        forgot to comment earlier and say thanks, I did find your answer very useful too.
        $endgroup$
        – benb
        Jun 1 at 12:31










      • $begingroup$
        @benb - I'm glad my answer helped you. Just wondering why you unaccepted my answer :(
        $endgroup$
        – Justin
        Jun 3 at 13:04










      • $begingroup$
        Sorry about that, there's nothing wrong with your answer. I've actually started using f-strings because of your advice, thank you. It was difficult to pick ONE answer, and I decided on AJNeufelds because other beginners reading this would probably benefit from the extra things his answer covers (e.g., not to use global variable names as function names etc.).
        $endgroup$
        – benb
        Jun 4 at 4:08






      • 1




        $begingroup$
        @benb - No worries. Just so know, I've also provided a link to PEP 8, which is Python's official style guide. It should help you with formatting and style in every possible way.
        $endgroup$
        – Justin
        Jun 4 at 4:13












      • 1




        $begingroup$
        forgot to comment earlier and say thanks, I did find your answer very useful too.
        $endgroup$
        – benb
        Jun 1 at 12:31










      • $begingroup$
        @benb - I'm glad my answer helped you. Just wondering why you unaccepted my answer :(
        $endgroup$
        – Justin
        Jun 3 at 13:04










      • $begingroup$
        Sorry about that, there's nothing wrong with your answer. I've actually started using f-strings because of your advice, thank you. It was difficult to pick ONE answer, and I decided on AJNeufelds because other beginners reading this would probably benefit from the extra things his answer covers (e.g., not to use global variable names as function names etc.).
        $endgroup$
        – benb
        Jun 4 at 4:08






      • 1




        $begingroup$
        @benb - No worries. Just so know, I've also provided a link to PEP 8, which is Python's official style guide. It should help you with formatting and style in every possible way.
        $endgroup$
        – Justin
        Jun 4 at 4:13







      1




      1




      $begingroup$
      forgot to comment earlier and say thanks, I did find your answer very useful too.
      $endgroup$
      – benb
      Jun 1 at 12:31




      $begingroup$
      forgot to comment earlier and say thanks, I did find your answer very useful too.
      $endgroup$
      – benb
      Jun 1 at 12:31












      $begingroup$
      @benb - I'm glad my answer helped you. Just wondering why you unaccepted my answer :(
      $endgroup$
      – Justin
      Jun 3 at 13:04




      $begingroup$
      @benb - I'm glad my answer helped you. Just wondering why you unaccepted my answer :(
      $endgroup$
      – Justin
      Jun 3 at 13:04












      $begingroup$
      Sorry about that, there's nothing wrong with your answer. I've actually started using f-strings because of your advice, thank you. It was difficult to pick ONE answer, and I decided on AJNeufelds because other beginners reading this would probably benefit from the extra things his answer covers (e.g., not to use global variable names as function names etc.).
      $endgroup$
      – benb
      Jun 4 at 4:08




      $begingroup$
      Sorry about that, there's nothing wrong with your answer. I've actually started using f-strings because of your advice, thank you. It was difficult to pick ONE answer, and I decided on AJNeufelds because other beginners reading this would probably benefit from the extra things his answer covers (e.g., not to use global variable names as function names etc.).
      $endgroup$
      – benb
      Jun 4 at 4:08




      1




      1




      $begingroup$
      @benb - No worries. Just so know, I've also provided a link to PEP 8, which is Python's official style guide. It should help you with formatting and style in every possible way.
      $endgroup$
      – Justin
      Jun 4 at 4:13




      $begingroup$
      @benb - No worries. Just so know, I've also provided a link to PEP 8, which is Python's official style guide. It should help you with formatting and style in every possible way.
      $endgroup$
      – Justin
      Jun 4 at 4:13











      9
















      $begingroup$


      1. If you need to add '' then you should do this outside of the function. This can be fairly easy knowing the output is always a string.



        >>> print(repr(list_concatenator('a')))
        'a'


        By default the IDLE prompt does this automatically.



        >>> list_concatenator('a')
        'a'



      2. Rather than using len(your_list) == 0 you can use not your_list.



        if not your_list:
        return 'Your list is empty'


      3. You can use str.join to join the rest of your lists.


      def list_concatenator(your_list, comma=', ', conjunction=' and '):
      if not your_list:
      return 'Your list is empty'

      your_list = [str(i) for i in your_list]
      if len(your_list) > 1:
      your_list[:-1] = [comma.join(your_list[:-1])]
      return conjunction.join(your_list)

      >>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
      'item1, item2, 3, item4, item5, item6, 7, item8 and 9'
      >>> list_concatenator('abcde', conjunction=' or ')
      'a, b, c, d or e'
      >>> list_concatenator('abcde', conjunction=', or ')
      'a, b, c, d, or e'
      >>> list_concatenator('ab')
      'a and b'
      >>> list_concatenator('a')
      'a'



      It should be noted that the challenge says to seperate each value with a ', ', and so you could simplify this by mutating the last value with the conjunction, and just use one str.join.



      def list_concatenator(your_list, comma=', ', conjunction='and'):
      if not your_list:
      return 'Your list is empty'

      your_list = [str(i) for i in your_list]
      if len(your_list) > 1:
      your_list[-1] = conjunction + ' ' + your_list[-1]
      return comma.join(your_list)

      >>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
      'item1, item2, 3, item4, item5, item6, 7, item8, and 9'
      >>> list_concatenator('abcde', conjunction='or')
      'a, b, c, d, or e'
      >>> list_concatenator('ab')
      'a, and b'
      >>> list_concatenator('a')
      'a'





      share|improve this answer












      $endgroup$










      • 1




        $begingroup$
        Posting on behalf of a_faulty_star. a_faulty_star: P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!
        $endgroup$
        – benb
        May 31 at 8:18






      • 1




        $begingroup$
        @benb It was in your original code. You should be able to see how to remove them if you need to.
        $endgroup$
        – Peilonrayz
        May 31 at 8:22






      • 2




        $begingroup$
        In my original code the output looked like 'item1, item2' etc., with the whole string having ' ' around it. What a_faulty_star is pointing out is in the above code the output is 'item1', 'item2' two etc., with each item having it's own quotes. As you said, you can fix it by taking out the double quotes "" in your_list = [f"'i'" for i in your_list].
        $endgroup$
        – benb
        May 31 at 8:41






      • 2




        $begingroup$
        Ah, I misread your ' and ' as "' and '". I've changed it now.
        $endgroup$
        – Peilonrayz
        May 31 at 9:01















      9
















      $begingroup$


      1. If you need to add '' then you should do this outside of the function. This can be fairly easy knowing the output is always a string.



        >>> print(repr(list_concatenator('a')))
        'a'


        By default the IDLE prompt does this automatically.



        >>> list_concatenator('a')
        'a'



      2. Rather than using len(your_list) == 0 you can use not your_list.



        if not your_list:
        return 'Your list is empty'


      3. You can use str.join to join the rest of your lists.


      def list_concatenator(your_list, comma=', ', conjunction=' and '):
      if not your_list:
      return 'Your list is empty'

      your_list = [str(i) for i in your_list]
      if len(your_list) > 1:
      your_list[:-1] = [comma.join(your_list[:-1])]
      return conjunction.join(your_list)

      >>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
      'item1, item2, 3, item4, item5, item6, 7, item8 and 9'
      >>> list_concatenator('abcde', conjunction=' or ')
      'a, b, c, d or e'
      >>> list_concatenator('abcde', conjunction=', or ')
      'a, b, c, d, or e'
      >>> list_concatenator('ab')
      'a and b'
      >>> list_concatenator('a')
      'a'



      It should be noted that the challenge says to seperate each value with a ', ', and so you could simplify this by mutating the last value with the conjunction, and just use one str.join.



      def list_concatenator(your_list, comma=', ', conjunction='and'):
      if not your_list:
      return 'Your list is empty'

      your_list = [str(i) for i in your_list]
      if len(your_list) > 1:
      your_list[-1] = conjunction + ' ' + your_list[-1]
      return comma.join(your_list)

      >>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
      'item1, item2, 3, item4, item5, item6, 7, item8, and 9'
      >>> list_concatenator('abcde', conjunction='or')
      'a, b, c, d, or e'
      >>> list_concatenator('ab')
      'a, and b'
      >>> list_concatenator('a')
      'a'





      share|improve this answer












      $endgroup$










      • 1




        $begingroup$
        Posting on behalf of a_faulty_star. a_faulty_star: P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!
        $endgroup$
        – benb
        May 31 at 8:18






      • 1




        $begingroup$
        @benb It was in your original code. You should be able to see how to remove them if you need to.
        $endgroup$
        – Peilonrayz
        May 31 at 8:22






      • 2




        $begingroup$
        In my original code the output looked like 'item1, item2' etc., with the whole string having ' ' around it. What a_faulty_star is pointing out is in the above code the output is 'item1', 'item2' two etc., with each item having it's own quotes. As you said, you can fix it by taking out the double quotes "" in your_list = [f"'i'" for i in your_list].
        $endgroup$
        – benb
        May 31 at 8:41






      • 2




        $begingroup$
        Ah, I misread your ' and ' as "' and '". I've changed it now.
        $endgroup$
        – Peilonrayz
        May 31 at 9:01













      9














      9










      9







      $begingroup$


      1. If you need to add '' then you should do this outside of the function. This can be fairly easy knowing the output is always a string.



        >>> print(repr(list_concatenator('a')))
        'a'


        By default the IDLE prompt does this automatically.



        >>> list_concatenator('a')
        'a'



      2. Rather than using len(your_list) == 0 you can use not your_list.



        if not your_list:
        return 'Your list is empty'


      3. You can use str.join to join the rest of your lists.


      def list_concatenator(your_list, comma=', ', conjunction=' and '):
      if not your_list:
      return 'Your list is empty'

      your_list = [str(i) for i in your_list]
      if len(your_list) > 1:
      your_list[:-1] = [comma.join(your_list[:-1])]
      return conjunction.join(your_list)

      >>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
      'item1, item2, 3, item4, item5, item6, 7, item8 and 9'
      >>> list_concatenator('abcde', conjunction=' or ')
      'a, b, c, d or e'
      >>> list_concatenator('abcde', conjunction=', or ')
      'a, b, c, d, or e'
      >>> list_concatenator('ab')
      'a and b'
      >>> list_concatenator('a')
      'a'



      It should be noted that the challenge says to seperate each value with a ', ', and so you could simplify this by mutating the last value with the conjunction, and just use one str.join.



      def list_concatenator(your_list, comma=', ', conjunction='and'):
      if not your_list:
      return 'Your list is empty'

      your_list = [str(i) for i in your_list]
      if len(your_list) > 1:
      your_list[-1] = conjunction + ' ' + your_list[-1]
      return comma.join(your_list)

      >>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
      'item1, item2, 3, item4, item5, item6, 7, item8, and 9'
      >>> list_concatenator('abcde', conjunction='or')
      'a, b, c, d, or e'
      >>> list_concatenator('ab')
      'a, and b'
      >>> list_concatenator('a')
      'a'





      share|improve this answer












      $endgroup$




      1. If you need to add '' then you should do this outside of the function. This can be fairly easy knowing the output is always a string.



        >>> print(repr(list_concatenator('a')))
        'a'


        By default the IDLE prompt does this automatically.



        >>> list_concatenator('a')
        'a'



      2. Rather than using len(your_list) == 0 you can use not your_list.



        if not your_list:
        return 'Your list is empty'


      3. You can use str.join to join the rest of your lists.


      def list_concatenator(your_list, comma=', ', conjunction=' and '):
      if not your_list:
      return 'Your list is empty'

      your_list = [str(i) for i in your_list]
      if len(your_list) > 1:
      your_list[:-1] = [comma.join(your_list[:-1])]
      return conjunction.join(your_list)

      >>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
      'item1, item2, 3, item4, item5, item6, 7, item8 and 9'
      >>> list_concatenator('abcde', conjunction=' or ')
      'a, b, c, d or e'
      >>> list_concatenator('abcde', conjunction=', or ')
      'a, b, c, d, or e'
      >>> list_concatenator('ab')
      'a and b'
      >>> list_concatenator('a')
      'a'



      It should be noted that the challenge says to seperate each value with a ', ', and so you could simplify this by mutating the last value with the conjunction, and just use one str.join.



      def list_concatenator(your_list, comma=', ', conjunction='and'):
      if not your_list:
      return 'Your list is empty'

      your_list = [str(i) for i in your_list]
      if len(your_list) > 1:
      your_list[-1] = conjunction + ' ' + your_list[-1]
      return comma.join(your_list)

      >>> list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9])
      'item1, item2, 3, item4, item5, item6, 7, item8, and 9'
      >>> list_concatenator('abcde', conjunction='or')
      'a, b, c, d, or e'
      >>> list_concatenator('ab')
      'a, and b'
      >>> list_concatenator('a')
      'a'






      share|improve this answer















      share|improve this answer




      share|improve this answer








      edited May 31 at 9:01

























      answered May 30 at 14:10









      PeilonrayzPeilonrayz

      30.7k4 gold badges46 silver badges123 bronze badges




      30.7k4 gold badges46 silver badges123 bronze badges










      • 1




        $begingroup$
        Posting on behalf of a_faulty_star. a_faulty_star: P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!
        $endgroup$
        – benb
        May 31 at 8:18






      • 1




        $begingroup$
        @benb It was in your original code. You should be able to see how to remove them if you need to.
        $endgroup$
        – Peilonrayz
        May 31 at 8:22






      • 2




        $begingroup$
        In my original code the output looked like 'item1, item2' etc., with the whole string having ' ' around it. What a_faulty_star is pointing out is in the above code the output is 'item1', 'item2' two etc., with each item having it's own quotes. As you said, you can fix it by taking out the double quotes "" in your_list = [f"'i'" for i in your_list].
        $endgroup$
        – benb
        May 31 at 8:41






      • 2




        $begingroup$
        Ah, I misread your ' and ' as "' and '". I've changed it now.
        $endgroup$
        – Peilonrayz
        May 31 at 9:01












      • 1




        $begingroup$
        Posting on behalf of a_faulty_star. a_faulty_star: P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!
        $endgroup$
        – benb
        May 31 at 8:18






      • 1




        $begingroup$
        @benb It was in your original code. You should be able to see how to remove them if you need to.
        $endgroup$
        – Peilonrayz
        May 31 at 8:22






      • 2




        $begingroup$
        In my original code the output looked like 'item1, item2' etc., with the whole string having ' ' around it. What a_faulty_star is pointing out is in the above code the output is 'item1', 'item2' two etc., with each item having it's own quotes. As you said, you can fix it by taking out the double quotes "" in your_list = [f"'i'" for i in your_list].
        $endgroup$
        – benb
        May 31 at 8:41






      • 2




        $begingroup$
        Ah, I misread your ' and ' as "' and '". I've changed it now.
        $endgroup$
        – Peilonrayz
        May 31 at 9:01







      1




      1




      $begingroup$
      Posting on behalf of a_faulty_star. a_faulty_star: P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!
      $endgroup$
      – benb
      May 31 at 8:18




      $begingroup$
      Posting on behalf of a_faulty_star. a_faulty_star: P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!
      $endgroup$
      – benb
      May 31 at 8:18




      1




      1




      $begingroup$
      @benb It was in your original code. You should be able to see how to remove them if you need to.
      $endgroup$
      – Peilonrayz
      May 31 at 8:22




      $begingroup$
      @benb It was in your original code. You should be able to see how to remove them if you need to.
      $endgroup$
      – Peilonrayz
      May 31 at 8:22




      2




      2




      $begingroup$
      In my original code the output looked like 'item1, item2' etc., with the whole string having ' ' around it. What a_faulty_star is pointing out is in the above code the output is 'item1', 'item2' two etc., with each item having it's own quotes. As you said, you can fix it by taking out the double quotes "" in your_list = [f"'i'" for i in your_list].
      $endgroup$
      – benb
      May 31 at 8:41




      $begingroup$
      In my original code the output looked like 'item1, item2' etc., with the whole string having ' ' around it. What a_faulty_star is pointing out is in the above code the output is 'item1', 'item2' two etc., with each item having it's own quotes. As you said, you can fix it by taking out the double quotes "" in your_list = [f"'i'" for i in your_list].
      $endgroup$
      – benb
      May 31 at 8:41




      2




      2




      $begingroup$
      Ah, I misread your ' and ' as "' and '". I've changed it now.
      $endgroup$
      – Peilonrayz
      May 31 at 9:01




      $begingroup$
      Ah, I misread your ' and ' as "' and '". I've changed it now.
      $endgroup$
      – Peilonrayz
      May 31 at 9:01











      5
















      $begingroup$

      I used the following function for achieving the task. I am new here, so please feel free to comment anything you feel is wrong!



      In the function, firstly, I check if the given list is empty or not.



      If it is, then I return an empty string.



      Otherwise, I first store the length of string in a variable. Then, I use list comprehension to convert all the elements in the list to string format, because some of them may be non-string and cause an error while using join function. Then, I join the strings in the list, separated by a comma and space, by using the join function on all elements of the list except the last. Then, I add an 'and' if the list has three or more elements. I have added the Oxford comma and a space before 'and' because the question has mentioned it.



      Here is the function:



      >>> def list_concatenator(your_list):
      if not your_list:
      return ''
      your_list = [str(i) for i in your_list]
      p = len(your_list)
      return ', '.join(your_list[:-1]) + (',' if p>2 else '') + (' and ' if p>1 else '') + your_list[-1]


      Here are some outputs:



      >>> li = []
      >>> print(list_concatenator(li))


      >>> li2 = ['apples']
      >>> print(list_concatenator(li2))
      apples

      >>> li3 = ['apples', 'bananas']
      >>> print(list_concatenator(li3))
      apples and bananas

      >>> li4 = ['apples', 'bananas', 'tofu', 'cats']
      >>> print(list_concatenator(li4))
      apples, bananas, tofu, and cats

      >>> li5 = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]
      >>> print(list_concatenator(li5))
      item1, item2, 3, item4, item5, item6, 7, item8, and 9


      P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!






      share|improve this answer












      $endgroup$










      • 2




        $begingroup$
        I think this is a great solution. I will leave @AJNeufeld comment as the answer as I think it provides a lot of useful information for a beginner, but your solution seems to do everything required while also being very concise. Thanks.
        $endgroup$
        – benb
        May 31 at 8:21






      • 1




        $begingroup$
        I have left the code to work as close to the original code as possible. For ease of programming I changed from the oxford comma to what the spec defines. But the function works the same otherwise.
        $endgroup$
        – Peilonrayz
        May 31 at 8:25






      • 1




        $begingroup$
        @a_faulty_star - You have not implemented the Oxford comma in your answer. An Oxford comma is where lists with two items do not have commas but lists with more than two items are separated with commas. Here is the link - en.wikipedia.org/wiki/Serial_comma. Therefore, if you are using the Oxford comma, then your third output should be - apples and bananas.
        $endgroup$
        – Justin
        May 31 at 12:38






      • 3




        $begingroup$
        @a_faulty_star - No worries. Your answer is pretty close to a code review and you have already received 3 upvotes, which is amazing for a first attempt. As benb said, your solution is very concise, so it did help him. Kudos for writing your first answer on Code Review!
        $endgroup$
        – Justin
        May 31 at 13:21







      • 2




        $begingroup$
        Thank you @Justin. You and benb are too kind :')
        $endgroup$
        – a_faulty_star
        May 31 at 13:55















      5
















      $begingroup$

      I used the following function for achieving the task. I am new here, so please feel free to comment anything you feel is wrong!



      In the function, firstly, I check if the given list is empty or not.



      If it is, then I return an empty string.



      Otherwise, I first store the length of string in a variable. Then, I use list comprehension to convert all the elements in the list to string format, because some of them may be non-string and cause an error while using join function. Then, I join the strings in the list, separated by a comma and space, by using the join function on all elements of the list except the last. Then, I add an 'and' if the list has three or more elements. I have added the Oxford comma and a space before 'and' because the question has mentioned it.



      Here is the function:



      >>> def list_concatenator(your_list):
      if not your_list:
      return ''
      your_list = [str(i) for i in your_list]
      p = len(your_list)
      return ', '.join(your_list[:-1]) + (',' if p>2 else '') + (' and ' if p>1 else '') + your_list[-1]


      Here are some outputs:



      >>> li = []
      >>> print(list_concatenator(li))


      >>> li2 = ['apples']
      >>> print(list_concatenator(li2))
      apples

      >>> li3 = ['apples', 'bananas']
      >>> print(list_concatenator(li3))
      apples and bananas

      >>> li4 = ['apples', 'bananas', 'tofu', 'cats']
      >>> print(list_concatenator(li4))
      apples, bananas, tofu, and cats

      >>> li5 = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]
      >>> print(list_concatenator(li5))
      item1, item2, 3, item4, item5, item6, 7, item8, and 9


      P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!






      share|improve this answer












      $endgroup$










      • 2




        $begingroup$
        I think this is a great solution. I will leave @AJNeufeld comment as the answer as I think it provides a lot of useful information for a beginner, but your solution seems to do everything required while also being very concise. Thanks.
        $endgroup$
        – benb
        May 31 at 8:21






      • 1




        $begingroup$
        I have left the code to work as close to the original code as possible. For ease of programming I changed from the oxford comma to what the spec defines. But the function works the same otherwise.
        $endgroup$
        – Peilonrayz
        May 31 at 8:25






      • 1




        $begingroup$
        @a_faulty_star - You have not implemented the Oxford comma in your answer. An Oxford comma is where lists with two items do not have commas but lists with more than two items are separated with commas. Here is the link - en.wikipedia.org/wiki/Serial_comma. Therefore, if you are using the Oxford comma, then your third output should be - apples and bananas.
        $endgroup$
        – Justin
        May 31 at 12:38






      • 3




        $begingroup$
        @a_faulty_star - No worries. Your answer is pretty close to a code review and you have already received 3 upvotes, which is amazing for a first attempt. As benb said, your solution is very concise, so it did help him. Kudos for writing your first answer on Code Review!
        $endgroup$
        – Justin
        May 31 at 13:21







      • 2




        $begingroup$
        Thank you @Justin. You and benb are too kind :')
        $endgroup$
        – a_faulty_star
        May 31 at 13:55













      5














      5










      5







      $begingroup$

      I used the following function for achieving the task. I am new here, so please feel free to comment anything you feel is wrong!



      In the function, firstly, I check if the given list is empty or not.



      If it is, then I return an empty string.



      Otherwise, I first store the length of string in a variable. Then, I use list comprehension to convert all the elements in the list to string format, because some of them may be non-string and cause an error while using join function. Then, I join the strings in the list, separated by a comma and space, by using the join function on all elements of the list except the last. Then, I add an 'and' if the list has three or more elements. I have added the Oxford comma and a space before 'and' because the question has mentioned it.



      Here is the function:



      >>> def list_concatenator(your_list):
      if not your_list:
      return ''
      your_list = [str(i) for i in your_list]
      p = len(your_list)
      return ', '.join(your_list[:-1]) + (',' if p>2 else '') + (' and ' if p>1 else '') + your_list[-1]


      Here are some outputs:



      >>> li = []
      >>> print(list_concatenator(li))


      >>> li2 = ['apples']
      >>> print(list_concatenator(li2))
      apples

      >>> li3 = ['apples', 'bananas']
      >>> print(list_concatenator(li3))
      apples and bananas

      >>> li4 = ['apples', 'bananas', 'tofu', 'cats']
      >>> print(list_concatenator(li4))
      apples, bananas, tofu, and cats

      >>> li5 = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]
      >>> print(list_concatenator(li5))
      item1, item2, 3, item4, item5, item6, 7, item8, and 9


      P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!






      share|improve this answer












      $endgroup$



      I used the following function for achieving the task. I am new here, so please feel free to comment anything you feel is wrong!



      In the function, firstly, I check if the given list is empty or not.



      If it is, then I return an empty string.



      Otherwise, I first store the length of string in a variable. Then, I use list comprehension to convert all the elements in the list to string format, because some of them may be non-string and cause an error while using join function. Then, I join the strings in the list, separated by a comma and space, by using the join function on all elements of the list except the last. Then, I add an 'and' if the list has three or more elements. I have added the Oxford comma and a space before 'and' because the question has mentioned it.



      Here is the function:



      >>> def list_concatenator(your_list):
      if not your_list:
      return ''
      your_list = [str(i) for i in your_list]
      p = len(your_list)
      return ', '.join(your_list[:-1]) + (',' if p>2 else '') + (' and ' if p>1 else '') + your_list[-1]


      Here are some outputs:



      >>> li = []
      >>> print(list_concatenator(li))


      >>> li2 = ['apples']
      >>> print(list_concatenator(li2))
      apples

      >>> li3 = ['apples', 'bananas']
      >>> print(list_concatenator(li3))
      apples and bananas

      >>> li4 = ['apples', 'bananas', 'tofu', 'cats']
      >>> print(list_concatenator(li4))
      apples, bananas, tofu, and cats

      >>> li5 = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]
      >>> print(list_concatenator(li5))
      item1, item2, 3, item4, item5, item6, 7, item8, and 9


      P.S: I have noticed that the outputs in Peilonrayz's answer have single quotes for every element of the input list, which is not the desired output. As I don't have 150 reputation, I can't comment :( But if someone who has 150 reputation notices this, please inform them! Thanks!







      share|improve this answer















      share|improve this answer




      share|improve this answer








      edited May 31 at 13:57

























      answered May 31 at 7:40









      a_faulty_stara_faulty_star

      515 bronze badges




      515 bronze badges










      • 2




        $begingroup$
        I think this is a great solution. I will leave @AJNeufeld comment as the answer as I think it provides a lot of useful information for a beginner, but your solution seems to do everything required while also being very concise. Thanks.
        $endgroup$
        – benb
        May 31 at 8:21






      • 1




        $begingroup$
        I have left the code to work as close to the original code as possible. For ease of programming I changed from the oxford comma to what the spec defines. But the function works the same otherwise.
        $endgroup$
        – Peilonrayz
        May 31 at 8:25






      • 1




        $begingroup$
        @a_faulty_star - You have not implemented the Oxford comma in your answer. An Oxford comma is where lists with two items do not have commas but lists with more than two items are separated with commas. Here is the link - en.wikipedia.org/wiki/Serial_comma. Therefore, if you are using the Oxford comma, then your third output should be - apples and bananas.
        $endgroup$
        – Justin
        May 31 at 12:38






      • 3




        $begingroup$
        @a_faulty_star - No worries. Your answer is pretty close to a code review and you have already received 3 upvotes, which is amazing for a first attempt. As benb said, your solution is very concise, so it did help him. Kudos for writing your first answer on Code Review!
        $endgroup$
        – Justin
        May 31 at 13:21







      • 2




        $begingroup$
        Thank you @Justin. You and benb are too kind :')
        $endgroup$
        – a_faulty_star
        May 31 at 13:55












      • 2




        $begingroup$
        I think this is a great solution. I will leave @AJNeufeld comment as the answer as I think it provides a lot of useful information for a beginner, but your solution seems to do everything required while also being very concise. Thanks.
        $endgroup$
        – benb
        May 31 at 8:21






      • 1




        $begingroup$
        I have left the code to work as close to the original code as possible. For ease of programming I changed from the oxford comma to what the spec defines. But the function works the same otherwise.
        $endgroup$
        – Peilonrayz
        May 31 at 8:25






      • 1




        $begingroup$
        @a_faulty_star - You have not implemented the Oxford comma in your answer. An Oxford comma is where lists with two items do not have commas but lists with more than two items are separated with commas. Here is the link - en.wikipedia.org/wiki/Serial_comma. Therefore, if you are using the Oxford comma, then your third output should be - apples and bananas.
        $endgroup$
        – Justin
        May 31 at 12:38






      • 3




        $begingroup$
        @a_faulty_star - No worries. Your answer is pretty close to a code review and you have already received 3 upvotes, which is amazing for a first attempt. As benb said, your solution is very concise, so it did help him. Kudos for writing your first answer on Code Review!
        $endgroup$
        – Justin
        May 31 at 13:21







      • 2




        $begingroup$
        Thank you @Justin. You and benb are too kind :')
        $endgroup$
        – a_faulty_star
        May 31 at 13:55







      2




      2




      $begingroup$
      I think this is a great solution. I will leave @AJNeufeld comment as the answer as I think it provides a lot of useful information for a beginner, but your solution seems to do everything required while also being very concise. Thanks.
      $endgroup$
      – benb
      May 31 at 8:21




      $begingroup$
      I think this is a great solution. I will leave @AJNeufeld comment as the answer as I think it provides a lot of useful information for a beginner, but your solution seems to do everything required while also being very concise. Thanks.
      $endgroup$
      – benb
      May 31 at 8:21




      1




      1




      $begingroup$
      I have left the code to work as close to the original code as possible. For ease of programming I changed from the oxford comma to what the spec defines. But the function works the same otherwise.
      $endgroup$
      – Peilonrayz
      May 31 at 8:25




      $begingroup$
      I have left the code to work as close to the original code as possible. For ease of programming I changed from the oxford comma to what the spec defines. But the function works the same otherwise.
      $endgroup$
      – Peilonrayz
      May 31 at 8:25




      1




      1




      $begingroup$
      @a_faulty_star - You have not implemented the Oxford comma in your answer. An Oxford comma is where lists with two items do not have commas but lists with more than two items are separated with commas. Here is the link - en.wikipedia.org/wiki/Serial_comma. Therefore, if you are using the Oxford comma, then your third output should be - apples and bananas.
      $endgroup$
      – Justin
      May 31 at 12:38




      $begingroup$
      @a_faulty_star - You have not implemented the Oxford comma in your answer. An Oxford comma is where lists with two items do not have commas but lists with more than two items are separated with commas. Here is the link - en.wikipedia.org/wiki/Serial_comma. Therefore, if you are using the Oxford comma, then your third output should be - apples and bananas.
      $endgroup$
      – Justin
      May 31 at 12:38




      3




      3




      $begingroup$
      @a_faulty_star - No worries. Your answer is pretty close to a code review and you have already received 3 upvotes, which is amazing for a first attempt. As benb said, your solution is very concise, so it did help him. Kudos for writing your first answer on Code Review!
      $endgroup$
      – Justin
      May 31 at 13:21





      $begingroup$
      @a_faulty_star - No worries. Your answer is pretty close to a code review and you have already received 3 upvotes, which is amazing for a first attempt. As benb said, your solution is very concise, so it did help him. Kudos for writing your first answer on Code Review!
      $endgroup$
      – Justin
      May 31 at 13:21





      2




      2




      $begingroup$
      Thank you @Justin. You and benb are too kind :')
      $endgroup$
      – a_faulty_star
      May 31 at 13:55




      $begingroup$
      Thank you @Justin. You and benb are too kind :')
      $endgroup$
      – a_faulty_star
      May 31 at 13:55











      3
















      $begingroup$

      Here are a few mostly stylistic points.



       def list_concatenator(your_list):


      "list_concatenator" is a poor choice for a function name. I'd rather expect "concatenator" to be a class that provides concatenation. A function name is, more commonly, a verb, that tells what the function does (e.g. sort) or a noun describing what the function returns (e.g. sqrt). Besides, "concatenate a list" is a very vague description of the task at hand. Therefore I'd suggest to name your function like "join_with_serial_comma" or "oxford_comma_concat" or even "oxfordize" ;)



      "your_list" is bad too (who's this "you" exactly?). It's just some list, so name it "some_list" or "a_list" or "lst". Moreover, since you're only using len and [] in your code, there's no reason to restrict your function to lists specifically, just make it accept any sequence and name your argument like "sequence" or "seq"



       items = len(your_list)


      Again, poor variable naming. items is what the list contains (cf. dict.items), what you mean here is length, size, number_of_items and so on.



       if items == 0:
      return 'Your list is empty'


      An empty list is an exceptional situation for your function, and you can't and shouldn't return any value in this case. Much better option would be to raise an exception (ValueError would be a good choice), better yet, just remove this condition, the rest of the code is going to break anyways if the argument is empty (or not a sequence at all, for that matter). Ask forgiveness, not permission.



       elif items == 1:
      return "'" + str(your_list[0]) + "'"


      If the previous condition ends with return or raise, there's no need for elif, just if would be more readable.



       elif items == 2:
      return "'" + str(your_list[0]) + ' and ' + str(your_list[1]) + "'"


      As said in other posts, format or f-strings are usually more readable than concatenation.



       else:
      your_list_split1 = (', '.join((map(str,your_list[:-1]))))
      return "'" + your_list_split1 + ', and ' + str(your_list[-1]) + "'"


      Yet again, your_list_split1 is a weird variable name, and doesn't reflect what the variable actually contains.



      Since you always return from other branches, you can remove else here and reduce the indentation.



      Comprehensions are usually more readable in python than map:



       head = ', '.join(str(item) for item in sequence[:-1])


      A more "pythonic" alternative to -1 indexing would be an unpacking assignment:



       *head, tail = seq
      head_joined = ', '.join(str(p) for p in head)
      return f'head_joined, and tail'


      Hope this helps.






      share|improve this answer












      $endgroup$



















        3
















        $begingroup$

        Here are a few mostly stylistic points.



         def list_concatenator(your_list):


        "list_concatenator" is a poor choice for a function name. I'd rather expect "concatenator" to be a class that provides concatenation. A function name is, more commonly, a verb, that tells what the function does (e.g. sort) or a noun describing what the function returns (e.g. sqrt). Besides, "concatenate a list" is a very vague description of the task at hand. Therefore I'd suggest to name your function like "join_with_serial_comma" or "oxford_comma_concat" or even "oxfordize" ;)



        "your_list" is bad too (who's this "you" exactly?). It's just some list, so name it "some_list" or "a_list" or "lst". Moreover, since you're only using len and [] in your code, there's no reason to restrict your function to lists specifically, just make it accept any sequence and name your argument like "sequence" or "seq"



         items = len(your_list)


        Again, poor variable naming. items is what the list contains (cf. dict.items), what you mean here is length, size, number_of_items and so on.



         if items == 0:
        return 'Your list is empty'


        An empty list is an exceptional situation for your function, and you can't and shouldn't return any value in this case. Much better option would be to raise an exception (ValueError would be a good choice), better yet, just remove this condition, the rest of the code is going to break anyways if the argument is empty (or not a sequence at all, for that matter). Ask forgiveness, not permission.



         elif items == 1:
        return "'" + str(your_list[0]) + "'"


        If the previous condition ends with return or raise, there's no need for elif, just if would be more readable.



         elif items == 2:
        return "'" + str(your_list[0]) + ' and ' + str(your_list[1]) + "'"


        As said in other posts, format or f-strings are usually more readable than concatenation.



         else:
        your_list_split1 = (', '.join((map(str,your_list[:-1]))))
        return "'" + your_list_split1 + ', and ' + str(your_list[-1]) + "'"


        Yet again, your_list_split1 is a weird variable name, and doesn't reflect what the variable actually contains.



        Since you always return from other branches, you can remove else here and reduce the indentation.



        Comprehensions are usually more readable in python than map:



         head = ', '.join(str(item) for item in sequence[:-1])


        A more "pythonic" alternative to -1 indexing would be an unpacking assignment:



         *head, tail = seq
        head_joined = ', '.join(str(p) for p in head)
        return f'head_joined, and tail'


        Hope this helps.






        share|improve this answer












        $endgroup$

















          3














          3










          3







          $begingroup$

          Here are a few mostly stylistic points.



           def list_concatenator(your_list):


          "list_concatenator" is a poor choice for a function name. I'd rather expect "concatenator" to be a class that provides concatenation. A function name is, more commonly, a verb, that tells what the function does (e.g. sort) or a noun describing what the function returns (e.g. sqrt). Besides, "concatenate a list" is a very vague description of the task at hand. Therefore I'd suggest to name your function like "join_with_serial_comma" or "oxford_comma_concat" or even "oxfordize" ;)



          "your_list" is bad too (who's this "you" exactly?). It's just some list, so name it "some_list" or "a_list" or "lst". Moreover, since you're only using len and [] in your code, there's no reason to restrict your function to lists specifically, just make it accept any sequence and name your argument like "sequence" or "seq"



           items = len(your_list)


          Again, poor variable naming. items is what the list contains (cf. dict.items), what you mean here is length, size, number_of_items and so on.



           if items == 0:
          return 'Your list is empty'


          An empty list is an exceptional situation for your function, and you can't and shouldn't return any value in this case. Much better option would be to raise an exception (ValueError would be a good choice), better yet, just remove this condition, the rest of the code is going to break anyways if the argument is empty (or not a sequence at all, for that matter). Ask forgiveness, not permission.



           elif items == 1:
          return "'" + str(your_list[0]) + "'"


          If the previous condition ends with return or raise, there's no need for elif, just if would be more readable.



           elif items == 2:
          return "'" + str(your_list[0]) + ' and ' + str(your_list[1]) + "'"


          As said in other posts, format or f-strings are usually more readable than concatenation.



           else:
          your_list_split1 = (', '.join((map(str,your_list[:-1]))))
          return "'" + your_list_split1 + ', and ' + str(your_list[-1]) + "'"


          Yet again, your_list_split1 is a weird variable name, and doesn't reflect what the variable actually contains.



          Since you always return from other branches, you can remove else here and reduce the indentation.



          Comprehensions are usually more readable in python than map:



           head = ', '.join(str(item) for item in sequence[:-1])


          A more "pythonic" alternative to -1 indexing would be an unpacking assignment:



           *head, tail = seq
          head_joined = ', '.join(str(p) for p in head)
          return f'head_joined, and tail'


          Hope this helps.






          share|improve this answer












          $endgroup$



          Here are a few mostly stylistic points.



           def list_concatenator(your_list):


          "list_concatenator" is a poor choice for a function name. I'd rather expect "concatenator" to be a class that provides concatenation. A function name is, more commonly, a verb, that tells what the function does (e.g. sort) or a noun describing what the function returns (e.g. sqrt). Besides, "concatenate a list" is a very vague description of the task at hand. Therefore I'd suggest to name your function like "join_with_serial_comma" or "oxford_comma_concat" or even "oxfordize" ;)



          "your_list" is bad too (who's this "you" exactly?). It's just some list, so name it "some_list" or "a_list" or "lst". Moreover, since you're only using len and [] in your code, there's no reason to restrict your function to lists specifically, just make it accept any sequence and name your argument like "sequence" or "seq"



           items = len(your_list)


          Again, poor variable naming. items is what the list contains (cf. dict.items), what you mean here is length, size, number_of_items and so on.



           if items == 0:
          return 'Your list is empty'


          An empty list is an exceptional situation for your function, and you can't and shouldn't return any value in this case. Much better option would be to raise an exception (ValueError would be a good choice), better yet, just remove this condition, the rest of the code is going to break anyways if the argument is empty (or not a sequence at all, for that matter). Ask forgiveness, not permission.



           elif items == 1:
          return "'" + str(your_list[0]) + "'"


          If the previous condition ends with return or raise, there's no need for elif, just if would be more readable.



           elif items == 2:
          return "'" + str(your_list[0]) + ' and ' + str(your_list[1]) + "'"


          As said in other posts, format or f-strings are usually more readable than concatenation.



           else:
          your_list_split1 = (', '.join((map(str,your_list[:-1]))))
          return "'" + your_list_split1 + ', and ' + str(your_list[-1]) + "'"


          Yet again, your_list_split1 is a weird variable name, and doesn't reflect what the variable actually contains.



          Since you always return from other branches, you can remove else here and reduce the indentation.



          Comprehensions are usually more readable in python than map:



           head = ', '.join(str(item) for item in sequence[:-1])


          A more "pythonic" alternative to -1 indexing would be an unpacking assignment:



           *head, tail = seq
          head_joined = ', '.join(str(p) for p in head)
          return f'head_joined, and tail'


          Hope this helps.







          share|improve this answer















          share|improve this answer




          share|improve this answer








          edited May 31 at 8:52

























          answered May 31 at 8:35









          georggeorg

          5062 silver badges4 bronze badges




          5062 silver badges4 bronze badges
























              2
















              $begingroup$

              Slicing the list would allow you to get all except the last element. Testing the list length will indicate what needs to go before the final element.



              if len(your_list) > 0:
              if len(your_list) > 2: ander = ',' # if passive comma needed
              if len(your_list) > 1: ander += ' and '
              ', '.join(your_list[0:-1]) + ander + thelist[-1]





              share|improve this answer










              $endgroup$



















                2
















                $begingroup$

                Slicing the list would allow you to get all except the last element. Testing the list length will indicate what needs to go before the final element.



                if len(your_list) > 0:
                if len(your_list) > 2: ander = ',' # if passive comma needed
                if len(your_list) > 1: ander += ' and '
                ', '.join(your_list[0:-1]) + ander + thelist[-1]





                share|improve this answer










                $endgroup$

















                  2














                  2










                  2







                  $begingroup$

                  Slicing the list would allow you to get all except the last element. Testing the list length will indicate what needs to go before the final element.



                  if len(your_list) > 0:
                  if len(your_list) > 2: ander = ',' # if passive comma needed
                  if len(your_list) > 1: ander += ' and '
                  ', '.join(your_list[0:-1]) + ander + thelist[-1]





                  share|improve this answer










                  $endgroup$



                  Slicing the list would allow you to get all except the last element. Testing the list length will indicate what needs to go before the final element.



                  if len(your_list) > 0:
                  if len(your_list) > 2: ander = ',' # if passive comma needed
                  if len(your_list) > 1: ander += ' and '
                  ', '.join(your_list[0:-1]) + ander + thelist[-1]






                  share|improve this answer













                  share|improve this answer




                  share|improve this answer










                  answered May 31 at 19:00









                  litlit

                  1212 bronze badges




                  1212 bronze badges































                      draft saved

                      draft discarded















































                      Thanks for contributing an answer to Code Review Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      Use MathJax to format equations. MathJax reference.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f221318%2fcomma-code-ch-4-automate-the-boring-stuff%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown









                      Popular posts from this blog

                      Tamil (spriik) Luke uk diar | Nawigatjuun

                      Align equal signs while including text over equalitiesAMS align: left aligned text/math plus multicolumn alignmentMultiple alignmentsAligning equations in multiple placesNumbering and aligning an equation with multiple columnsHow to align one equation with another multline equationUsing \ in environments inside the begintabularxNumber equations and preserving alignment of equal signsHow can I align equations to the left and to the right?Double equation alignment problem within align enviromentAligned within align: Why are they right-aligned?

                      Where does the image of a data connector as a sharp metal spike originate from?Where does the concept of infected people turning into zombies only after death originate from?Where does the motif of a reanimated human head originate?Where did the notion that Dragons could speak originate?Where does the archetypal image of the 'Grey' alien come from?Where did the suffix '-Man' originate?Where does the notion of being injured or killed by an illusion originate?Where did the term “sophont” originate?Where does the trope of magic spells being driven by advanced technology originate from?Where did the term “the living impaired” originate?