Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #53335 > unrolled thread
| Started by | candide <candide@free.invalid> |
|---|---|
| First post | 2013-08-31 10:17 +0200 |
| Last post | 2013-09-12 15:25 -0400 |
| Articles | 20 on this page of 22 — 11 participants |
Back to article view | Back to comp.lang.python
print function and unwanted trailing space candide <candide@free.invalid> - 2013-08-31 10:17 +0200
Re: print function and unwanted trailing space Andreas Perstinger <andipersti@gmail.com> - 2013-08-31 10:43 +0200
Re: print function and unwanted trailing space candide <candide@free.invalid> - 2013-08-31 11:25 +0200
Re: print function and unwanted trailing space Peter Otten <__peter__@web.de> - 2013-08-31 12:31 +0200
Re: print function and unwanted trailing space candide <candide@free.invalid> - 2013-08-31 15:33 +0200
Re: print function and unwanted trailing space Peter Otten <__peter__@web.de> - 2013-08-31 15:59 +0200
Re: print function and unwanted trailing space candide <candide@free.invalid> - 2013-08-31 17:58 +0200
Re: print function and unwanted trailing space Chris Angelico <rosuav@gmail.com> - 2013-09-01 01:30 +1000
Re: print function and unwanted trailing space Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2013-08-31 16:43 +0100
Re: print function and unwanted trailing space Chris Angelico <rosuav@gmail.com> - 2013-09-01 08:08 +1000
Re: print function and unwanted trailing space Joshua Landau <joshua@landau.ws> - 2013-09-01 00:15 +0100
Re: print function and unwanted trailing space Terry Reedy <tjreedy@udel.edu> - 2013-08-31 19:57 -0400
Re: print function and unwanted trailing space candide <candide@free.invalid> - 2013-08-31 17:51 +0200
Re: print function and unwanted trailing space Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-31 11:16 +0000
Re: print function and unwanted trailing space Peter Otten <__peter__@web.de> - 2013-08-31 14:27 +0200
Re: print function and unwanted trailing space Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2013-08-31 13:37 +0100
Re: print function and unwanted trailing space candide <candide@free.invalid> - 2013-08-31 14:59 +0200
Re: print function and unwanted trailing space Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-31 15:18 +0000
Re: print function and unwanted trailing space Ned Batchelder <ned@nedbatchelder.com> - 2013-08-31 07:24 -0400
Re: print function and unwanted trailing space candide <candide@free.invalid> - 2013-08-31 15:51 +0200
Re: print function and unwanted trailing space Wayne Werner <wayne@waynewerner.com> - 2013-09-11 06:36 -0500
Re: print function and unwanted trailing space Albert Hopkins <marduk@letterboxes.org> - 2013-09-12 15:25 -0400
Page 1 of 2 [1] 2 Next page →
| From | candide <candide@free.invalid> |
|---|---|
| Date | 2013-08-31 10:17 +0200 |
| Subject | print function and unwanted trailing space |
| Message-ID | <5221a693$0$2059$426a74cc@news.free.fr> |
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()
# -----------------------------
[toc] | [next] | [standalone]
| From | Andreas Perstinger <andipersti@gmail.com> |
|---|---|
| Date | 2013-08-31 10:43 +0200 |
| Message-ID | <mailman.405.1377938644.19984.python-list@python.org> |
| In reply to | #53335 |
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
[toc] | [prev] | [next] | [standalone]
| From | candide <candide@free.invalid> |
|---|---|
| Date | 2013-08-31 11:25 +0200 |
| Message-ID | <5221b68b$0$2280$426a74cc@news.free.fr> |
| In reply to | #53338 |
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)).
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-08-31 12:31 +0200 |
| Message-ID | <mailman.406.1377945101.19984.python-list@python.org> |
| In reply to | #53339 |
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.
[toc] | [prev] | [next] | [standalone]
| From | candide <candide@free.invalid> |
|---|---|
| Date | 2013-08-31 15:33 +0200 |
| Message-ID | <5221f0af$0$2412$426a34cc@news.free.fr> |
| In reply to | #53341 |
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).
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-08-31 15:59 +0200 |
| Message-ID | <mailman.412.1377957573.19984.python-list@python.org> |
| In reply to | #53354 |
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))
[toc] | [prev] | [next] | [standalone]
| From | candide <candide@free.invalid> |
|---|---|
| Date | 2013-08-31 17:58 +0200 |
| Message-ID | <522212bf$0$2323$426a74cc@news.free.fr> |
| In reply to | #53356 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-09-01 01:30 +1000 |
| Message-ID | <mailman.415.1377963057.19984.python-list@python.org> |
| In reply to | #53354 |
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
[toc] | [prev] | [next] | [standalone]
| From | Oscar Benjamin <oscar.j.benjamin@gmail.com> |
|---|---|
| Date | 2013-08-31 16:43 +0100 |
| Message-ID | <mailman.416.1377963862.19984.python-list@python.org> |
| In reply to | #53354 |
On 31 August 2013 16:30, Chris Angelico <rosuav@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
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-09-01 08:08 +1000 |
| Message-ID | <mailman.422.1377986886.19984.python-list@python.org> |
| In reply to | #53354 |
On Sun, Sep 1, 2013 at 1:43 AM, Oscar Benjamin
<oscar.j.benjamin@gmail.com> wrote:
> On 31 August 2013 16:30, Chris Angelico <rosuav@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
[toc] | [prev] | [next] | [standalone]
| From | Joshua Landau <joshua@landau.ws> |
|---|---|
| Date | 2013-09-01 00:15 +0100 |
| Message-ID | <mailman.424.1377990970.19984.python-list@python.org> |
| In reply to | #53354 |
On 31 August 2013 23:08, Chris Angelico <rosuav@gmail.com> wrote:
> On Sun, Sep 1, 2013 at 1:43 AM, Oscar Benjamin
> <oscar.j.benjamin@gmail.com> wrote:
>> On 31 August 2013 16:30, Chris Angelico <rosuav@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.
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2013-08-31 19:57 -0400 |
| Message-ID | <mailman.429.1377993482.19984.python-list@python.org> |
| In reply to | #53354 |
On 8/31/2013 7:15 PM, Joshua Landau wrote:
> On 31 August 2013 23:08, Chris Angelico <rosuav@gmail.com> wrote:
>> On Sun, Sep 1, 2013 at 1:43 AM, Oscar Benjamin
>> <oscar.j.benjamin@gmail.com> wrote:
>>> On 31 August 2013 16:30, Chris Angelico <rosuav@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
[toc] | [prev] | [next] | [standalone]
| From | candide <candide@free.invalid> |
|---|---|
| Date | 2013-08-31 17:51 +0200 |
| Message-ID | <522210f8$0$13987$426a74cc@news.free.fr> |
| In reply to | #53341 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-08-31 11:16 +0000 |
| Message-ID | <5221d090$0$6599$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #53335 |
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
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-08-31 14:27 +0200 |
| Message-ID | <mailman.408.1377952066.19984.python-list@python.org> |
| In reply to | #53342 |
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'
[toc] | [prev] | [next] | [standalone]
| From | Oscar Benjamin <oscar.j.benjamin@gmail.com> |
|---|---|
| Date | 2013-08-31 13:37 +0100 |
| Message-ID | <mailman.410.1377952706.19984.python-list@python.org> |
| In reply to | #53342 |
On 31 August 2013 12:16, Steven D'Aprano
<steve+comp.lang.python@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
[toc] | [prev] | [next] | [standalone]
| From | candide <candide@free.invalid> |
|---|---|
| Date | 2013-08-31 14:59 +0200 |
| Message-ID | <5221e8a5$0$2105$426a74cc@news.free.fr> |
| In reply to | #53342 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-08-31 15:18 +0000 |
| Message-ID | <5222092a$0$6599$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #53352 |
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
[toc] | [prev] | [next] | [standalone]
| From | Ned Batchelder <ned@nedbatchelder.com> |
|---|---|
| Date | 2013-08-31 07:24 -0400 |
| Message-ID | <mailman.407.1377948297.19984.python-list@python.org> |
| In reply to | #53335 |
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.
[toc] | [prev] | [next] | [standalone]
| From | candide <candide@free.invalid> |
|---|---|
| Date | 2013-08-31 15:51 +0200 |
| Message-ID | <5221f4d3$0$2051$426a74cc@news.free.fr> |
| In reply to | #53343 |
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.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web