Question

For example, I have a list of strings:

str_list =['one', 'two', 'three', 'four', 'five']

I want to print all of them on the screen with:

for c in str_list:
    print c
    print ', ' # word separator

which results in:

one, two, three, four, five,

Here, a comma is not necessary at the end of the line and I don't want to print it. How can I modify the code above not to print the last comma?

It can be solved with enumerate:

for idx, c in enumerate(str_list):
    print c
    if idx < len(str_list) - 1:
        print ','

However, I think there may be a more elegant way to handle this.

Edited: Maybe I thought I gave a too simple example. Suppose what if I should call function x() for each iteration except for the last one:

for idx, x in enumerate(list_x):
    if idx < len(list_x) - 1:
        something_right(x)
    else:
        something_wrong(x)
Was it helpful?

Solution 2

One problem with if idx < len(list_x) - 1: is that it only works with sequences and not more generically with any iterator. You could write your own generator that looks ahead and tells you whether you've reached the end.

def tag_last(iterable):
    """Given some iterable, returns (last, item), where last is only
    true if you are on the final iteration.
    """
    iterator = iter(iterable)
    gotone = False
    try:
        lookback = next(iterator)
        gotone = True
        while True:
            cur = next(iterator)
            yield False, lookback
            lookback = cur
    except StopIteration:
        if gotone:
            yield True, lookback
        raise StopIteration()

In python 2 it would look like:

>>> for last, i in tag_last(xrange(4)):
...     print(last, i)
... 
(False, 0)
(False, 1)
(False, 2)
(True, 3)
>>> for last, i in tag_last(xrange(1)):
...     print(last, i)
... 
(True, 0)
>>> for last, i in tag_last(xrange(0)):
...     print(last, i)
... 
>>> 

OTHER TIPS

Inside of ', '.join(['one', 'two', 'three', 'four', 'five']) there's some sort of iteration ;)

And this is actually the most elegant way.

Here's another one:

# Everything except the last element
for x in a[:-1]:
    print(x + ', ', end='')

# And the last element
print(a[-1])

Outputs one, two, three, four, five

I would do (you could do join, but it is unnecessary and this I think is much more elegant):

>>> print(*str_list, sep=', ')
one, two, three, four, five

Very few know about the optional sep argument in the print function- by default it is a whitespace. The * just unpacks the list into separate items to be printed.

EDIT:

For your example regarding a loop, you are checking a condition on each iteration, which is a bit silly.

Instead, just iterate up to the penultimate element (range(len(a)) - 1) and then when that loop is done only then call the something_wrong() function with the last element of a (a[-1]) as the argument.

If you're looking for a more generalized solution to skip the last element, then this might be useful:

a = ['a','b','c','d']
for element,_ in zip( a, range(len(a) - 1) ):
    doSomethingRight(element)
doSomethingWrong(a[-1])

Explanation:
zip will exit when the shorter of the lists is exhausted. So, by looping over a and a range one item shorter in length, you'll doSomethingRight() for all elements except the last one. Then call doSomethingWrong() for the last element.

In your example,

str_list = ['one', 'two', 'three', 'four', 'five']
word_seperator = ","; string_end = "!"
result = ""
for element,_ in zip( str_list, range( len(str_list) - 1 ) ):
    result += element + word_seperator    # This is my 'doSomethingRight()'
result += str_list[-1] + string_end    # This is my 'doSomethingWrong()'

Result: one,two,three,four,five!

Hope this helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top