Re: print function and unwanted trailing space
On Wed, Sep 11, 2013, at 07:36 AM, Wayne Werner wrote: On Sat, 31 Aug 2013, candide wrote: # - for i in range(5): print(i, end=' ') # - The last ' ' is unwanted print() # - Then why not define end='' instead? I think the OP meant that ' ' is wanted up until the final item.. so something like for i in range(4): print(i, end=' ') print(4) or, better: print(' '.join(str(i) for i in range(5))) -- https://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On Sat, 31 Aug 2013, candide wrote: # - for i in range(5): print(i, end=' ') # - The last ' ' is unwanted print() # - Then why not define end='' instead? -W -- https://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On 31.08.2013 10:17, candide wrote: What is the equivalent in Python 3 to the following Python 2 code: # - for i in range(5): print i, # - ? How about print( .join(str(i) for i in range(5))) 0 1 2 3 4 Bye, Andreas -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
Le 31/08/2013 10:43, Andreas Perstinger a écrit : How about print( .join(str(i) for i in range(5))) 0 1 2 3 4 Thanks for your answer. The output is stricly the same but the code doesn't suit my needs : 1) I'm porting to Python 3 a Python 2 full beginner course : the learners are not aware of the join method nor the str type nor generators stuff; 2) Your code introduce a (sometimes) useless conversion to str (consider a string instead of range(5)). -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
candide wrote: Le 31/08/2013 10:43, Andreas Perstinger a écrit : How about print( .join(str(i) for i in range(5))) 0 1 2 3 4 Thanks for your answer. The output is stricly the same but the code doesn't suit my needs : 1) I'm porting to Python 3 a Python 2 full beginner course : the learners are not aware of the join method nor the str type nor generators stuff; 2) Your code introduce a (sometimes) useless conversion to str (consider a string instead of range(5)). You are out of luck, the softspace mechanism, roughly softspace = False for i in range(5): if softspace: print(end= ) print(i, end=) softspace = True print() with `softspace` saved as a file attribute, is gone in Python3. But I don't think that someone who doesn't know it existed will miss the feature. Maybe you can allow for /some/ magic and introduce your students to print(*range(5)) early-on. -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On Sat, 31 Aug 2013 10:17:23 +0200, candide wrote: What is the equivalent in Python 3 to the following Python 2 code: # - for i in range(5): print i, # - ? Be careful that the above code doesn't add a trailing space after the last number in the list, Of course it does. Have you actually tried it? The interactive interpreter is tricky, because you cannot directly follow a for-loop with another statement. If you try, the interactive interpreter gives you an indentation error. But we can work around it by sticking everything inside an if block, like so: py if True: ... for i in range(5): ... print i, ... # could be pages of code here ... print FINISHED ... 0 1 2 3 4 FINISHED Or you could stick the code inside an exec, which doesn't have the same limitation as the interactive interpreter. This mimics the behaviour of code in a file: py exec for i in range(5): ... print i, ... print FINISHED ... 0 1 2 3 4 FINISHED The same results occur with any other Python 2.x, and indeed all the way back to Python 1.5 and older. hence the following Python 3 code isn't strictly equivalent: # - for i in range(5): print(i, end=' ') # - The last ' ' is unwanted print() The last space is exactly the same as you get in Python 2. But really, who cares about an extra invisible space? In non-interactive mode, the two are exactly the same (ignoring the extra print() call outside the loop), but even at the interactive interpreter, I'd like to see the code where an extra space makes a real difference. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On 8/31/13 4:17 AM, candide wrote: What is the equivalent in Python 3 to the following Python 2 code: # - for i in range(5): print i, # - ? Be careful that the above code doesn't add a trailing space after the last number in the list, hence the following Python 3 code isn't strictly equivalent: # - for i in range(5): print(i, end=' ') # - The last ' ' is unwanted print() # - For a beginner course, the trailing space is fine, use this code. They'll never notice the trailing space (I wouldn't have!) and to explain why the comma leaves off the last one takes a really advanced understanding of obscure details anyway. --Ned. -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
Steven D'Aprano wrote: On Sat, 31 Aug 2013 10:17:23 +0200, candide wrote: What is the equivalent in Python 3 to the following Python 2 code: # - for i in range(5): print i, # - ? Be careful that the above code doesn't add a trailing space after the last number in the list, Of course it does. Have you actually tried it? The interactive interpreter is tricky, because you cannot directly follow a for-loop with another statement. If you try, the interactive interpreter gives you an indentation error. But we can work around it by sticking everything inside an if block, like so: py if True: ... for i in range(5): ... print i, ... # could be pages of code here ... print FINISHED ... 0 1 2 3 4 FINISHED Or you could stick the code inside an exec, which doesn't have the same limitation as the interactive interpreter. This mimics the behaviour of code in a file: py exec for i in range(5): ... print i, ... print FINISHED ... 0 1 2 3 4 FINISHED The same results occur with any other Python 2.x, and indeed all the way back to Python 1.5 and older. Your test is flawed. The softspace mechanism ensures that there is a space *between* all printed items, but not *after* the last printed item. print FINISHED will add a space while print will not. Compare: with open(tmp.txt, w) as f: ... for i in range(3): print f, i, ... print f ... open(tmp.txt).read() '0 1 2\n' with open(tmp.txt, w) as f: ... for i in range(3): print f, i, ... print f, FINISHED ... open(tmp.txt).read() '0 1 2 FINISHED\n' -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On 31 August 2013 12:16, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Sat, 31 Aug 2013 10:17:23 +0200, candide wrote: What is the equivalent in Python 3 to the following Python 2 code: # - for i in range(5): print i, # - ? Be careful that the above code doesn't add a trailing space after the last number in the list, Of course it does. Have you actually tried it? The interactive interpreter is tricky, because you cannot directly follow a for-loop with another statement. If you try, the interactive interpreter gives you an indentation error. But we can work around it by sticking everything inside an if block, like so: py if True: ... for i in range(5): ... print i, ... # could be pages of code here ... print FINISHED ... 0 1 2 3 4 FINISHED The space is added by the final print statement, not the last one in the loop. Here's a demo that shows this: $ cat print.py for i in range(5): print i, print $ cat print3.py for i in range(5): print(i, end=' ') print() $ py -2.7 print.py | cat -A 0 1 2 3 4^M$ $ py -3.3 print3.py | cat -A 0 1 2 3 4 ^M$ (Notice the space between the 4 and ^M (which is cat's way of saying '\r'). [snip] hence the following Python 3 code isn't strictly equivalent: # - for i in range(5): print(i, end=' ') # - The last ' ' is unwanted print() The last space is exactly the same as you get in Python 2. But really, who cares about an extra invisible space? In non-interactive mode, the two are exactly the same (ignoring the extra print() call outside the loop), but even at the interactive interpreter, I'd like to see the code where an extra space makes a real difference. I seem to remember it breaking some unit test or doc test something when I first tried to port something using 2to3 (this is the replacement that 2to3 uses for print with a trailing comma). It's not so important for interactive terminal output but when you do 'python script.py output.dat' the unwanted space shouldn't be there. The soft-space feature is useful but stateful as Peter says and defies the normal concept of what happens when calling a function so it was removed when print became a function. Oscar -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
Le 31/08/2013 13:16, Steven D'Aprano a écrit : Of course it does. Have you actually tried it? Of course I did, redirecting the output to a file in order to spot an eventually trailing space. I did the same for the Python 3 code. -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
Le 31/08/2013 12:31, Peter Otten a écrit : softspace = False for i in range(5): if softspace: print(end= ) print(i, end=) softspace = True print() The if instruction imposes useless testing (we know in advance the problem to occur at the very end of the loop) and useless writing (writing ''). The following is clearer # - n=5 for i in range(n-1): print(i, end=' ') print(n-1) # - but doesn't solve all the cases (imagine a string or an iterator). -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
Le 31/08/2013 13:24, Ned Batchelder a écrit : For a beginner course, the trailing space is fine, use this code. I was really expecting there was a trick but I'll follow your advice, after all the trailing space is invisible! Nevertheless, this can be quite annoying. For instance, some automated program testing (cf. http://www.spoj.com/, http://acm.timus.ru/, etc) expect the exact output to get accepted, no byte more or a byte less. -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
candide wrote: Le 31/08/2013 12:31, Peter Otten a écrit : softspace = False for i in range(5): if softspace: print(end= ) print(i, end=) softspace = True print() The if instruction imposes useless testing (we know in advance the problem to occur at the very end of the loop) and useless writing (writing ''). To make it crystal clear, the above was to illustrate the algorithm used in Python 2, not a suggestion. Python 2 uses that useless testing -- which is cheap compared to actual I/O. The following is clearer # - n=5 for i in range(n-1): print(i, end=' ') print(n-1) # - but doesn't solve all the cases (imagine a string or an iterator). I still think you should live with a trailing space or go with my actual suggestion print(*range(5)) -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On Sat, 31 Aug 2013 14:59:17 +0200, candide wrote: Le 31/08/2013 13:16, Steven D'Aprano a écrit : Of course it does. Have you actually tried it? Of course I did, redirecting the output to a file in order to spot an eventually trailing space. I did the same for the Python 3 code. Fair enough. Seems like the print statement implementation in Python 2 is uglier than I imagined, keeping hidden state between invocations. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On Sat, Aug 31, 2013 at 11:33 PM, candide candide@free.invalid wrote: The if instruction imposes useless testing (we know in advance the problem to occur at the very end of the loop) and useless writing (writing ''). The following is clearer # - n=5 for i in range(n-1): print(i, end=' ') print(n-1) # - but doesn't solve all the cases (imagine a string or an iterator). Similar but maybe simpler, and copes with more arbitrary iterables: it=iter(range(5)) print(next(it), end='') for i in it: print('',i, end='') Also guarantees to use 'sep' between the elements, fwiw. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On 31 August 2013 16:30, Chris Angelico ros...@gmail.com wrote: but doesn't solve all the cases (imagine a string or an iterator). Similar but maybe simpler, and copes with more arbitrary iterables: it=iter(range(5)) print(next(it), end='') for i in it: print('',i, end='') If you want to work with arbitrary iterables then you'll want it = iter(iterable) try: val = next(it) except StopIteration: pass # Or raise or something? else: print(val, end='') for i in it: print('', i, end='') Oscar -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
Le 31/08/2013 12:31, Peter Otten a écrit : with `softspace` saved as a file attribute, is gone in Python3. After reading http://docs.python.org/3.0/whatsnew/3.0.html#print-is-a-function I understand what you meant by softspace. Thanks. -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
Le 31/08/2013 15:59, Peter Otten a écrit : To make it crystal clear, the above was to illustrate the algorithm used in Python 2, not a suggestion. Ok sorry, I misinterpreted. I still think you should live with a trailing space Are you sure ? The following code #-- import io output = io.StringIO() n=5 for i in range(n-1): print(i, end=' ', file=output) print(n-1, file=output) print(output.getvalue().count(' ')) #-- outputs 4, the correct number of space character. or go with my actual suggestion print(*range(5)) It's a very good suggestion (the best one in fact) but rather complicated to explain to pure novices in programming. -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On Sun, Sep 1, 2013 at 1:43 AM, Oscar Benjamin oscar.j.benja...@gmail.com wrote: On 31 August 2013 16:30, Chris Angelico ros...@gmail.com wrote: but doesn't solve all the cases (imagine a string or an iterator). Similar but maybe simpler, and copes with more arbitrary iterables: it=iter(range(5)) print(next(it), end='') for i in it: print('',i, end='') If you want to work with arbitrary iterables then you'll want it = iter(iterable) try: val = next(it) except StopIteration: pass # Or raise or something? else: print(val, end='') for i in it: print('', i, end='') I went with this version: except StopIteration: raise In other words, if it's going to bomb, let it bomb :) ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On 31 August 2013 23:08, Chris Angelico ros...@gmail.com wrote: On Sun, Sep 1, 2013 at 1:43 AM, Oscar Benjamin oscar.j.benja...@gmail.com wrote: On 31 August 2013 16:30, Chris Angelico ros...@gmail.com wrote: but doesn't solve all the cases (imagine a string or an iterator). Similar but maybe simpler, and copes with more arbitrary iterables: it=iter(range(5)) print(next(it), end='') for i in it: print('',i, end='') If you want to work with arbitrary iterables then you'll want it = iter(iterable) try: val = next(it) except StopIteration: pass # Or raise or something? else: print(val, end='') for i in it: print('', i, end='') I went with this version: except StopIteration: raise In other words, if it's going to bomb, let it bomb :) I think the point is that StopIteration is an unsafe error to raise. -- http://mail.python.org/mailman/listinfo/python-list
Re: print function and unwanted trailing space
On 8/31/2013 7:15 PM, Joshua Landau wrote: On 31 August 2013 23:08, Chris Angelico ros...@gmail.com wrote: On Sun, Sep 1, 2013 at 1:43 AM, Oscar Benjamin oscar.j.benja...@gmail.com wrote: On 31 August 2013 16:30, Chris Angelico ros...@gmail.com wrote: but doesn't solve all the cases (imagine a string or an iterator). Similar but maybe simpler, and copes with more arbitrary iterables: it=iter(range(5)) print(next(it), end='') for i in it: print('',i, end='') If you want to work with arbitrary iterables then you'll want it = iter(iterable) try: val = next(it) except StopIteration: pass # Or raise or something? else: print(val, end='') for i in it: print('', i, end='') I went with this version: except StopIteration: raise In other words, if it's going to bomb, let it bomb :) I think the point is that StopIteration is an unsafe error to raise. It should only be raised by iterator.__next__ method and caught by iterator user and not re-raised. Raise something like ValueError('empty iterable') from None instead. -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list