By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,206 Members | 1,020 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,206 IT Pros & Developers. It's quick & easy.

print is not a function

P: n/a
Hi,

quite often there is a need to just print out the items of a list.

[ prt(x) for x in my_list ]

that would be nice, except prt() does not exist, and print is a
statement not a function, hence cannot replace prt as of above.

I don't like to write d
def prt(x):
print x
beforehand and any lambda construct would not be so handy.
It should be a short one-liner.
Any ideas?

Karl

Jul 18 '05 #1
Share this Question
Share on Google+
19 Replies


P: n/a
On Wed, 08 Oct 2003 11:32:20 +0200, Karl Scalet <ne**@yebu.de> wrote:
Hi,

quite often there is a need to just print out the items of a list.

[ prt(x) for x in my_list ]

that would be nice, except prt() does not exist, and print is a
statement not a function, hence cannot replace prt as of above.

I don't like to write d
def prt(x):
print x
beforehand and any lambda construct would not be so handy.
It should be a short one-liner.
Any ideas?

Karl


How about,
import sys
sys.stdout.write("Hello world!\n") Hello world! help(sys)

[text snipped]
stdin -- standard input file object; used by raw_input() and
input()
stdout -- standard output file object; used by the print statement
stderr -- standard error object; used for error messages
By assigning other file objects (or objects that behave like
files)
to these, it is possible to redirect all of the interpreter's
I/O.
[text continues]

Hope it helps, with my best regards,
G. Rodrigues
Jul 18 '05 #2

P: n/a
Gonçalo Rodrigues wrote:
On Wed, 08 Oct 2003 11:32:20 +0200, Karl Scalet <ne**@yebu.de> wrote:

Hi,

quite often there is a need to just print out the items of a list.

[ prt(x) for x in my_list ]

that would be nice, except prt() does not exist, and print is a
statement not a function, hence cannot replace prt as of above.

I don't like to write d
def prt(x):
print x
beforehand and any lambda construct would not be so handy.
It should be a short one-liner.
Any ideas?

Karl

How about,

import sys
sys.stdout.write("Hello world!\n")


I came across this, but this requires an extra import sys
which not always is there, thanks anyhow.

Karl

Jul 18 '05 #3

P: n/a
Karl Scalet wrote:
...
>sys.stdout.write("Hello world!\n")


I came across this, but this requires an extra import sys
which not always is there, thanks anyhow.


Ah, hadn't seen this before I answered your other post.

Well. duplicating the print statement functionality in
a *built-in* function to let you abuse a list comprehemsion
for the side effects and throw away the results just ain't
gonna happen. Built-in functions are (or should be: there
may well be purges in Python 3.0) just for tasks so important
and widespread that an 'import' cannot be considered.
Alex

Jul 18 '05 #4

P: n/a
Karl Scalet wrote:
quite often there is a need to just print out the items of a list.

[ prt(x) for x in my_list ]

that would be nice, except prt() does not exist, and print is a
statement not a function, hence cannot replace prt as of above.

I don't like to write d
def prt(x):
print x
beforehand and any lambda construct would not be so handy.
It should be a short one-liner.
Any ideas?


How about
myList = "alpha beta gamma".split()
print "\n".join([str(x) for x in myList])

alpha
beta
gamma

This way you at least put the list resulting from the comprehension to some
use.
General rule: use list comprehensions only if you need a list, otherwise for
loops are both more efficient and clearer regarding the code's purpose.

Peter
Jul 18 '05 #5

P: n/a
Karl Scalet wrote:
Hi,

quite often there is a need to just print out the items of a list.

[ prt(x) for x in my_list ]
This is conceptually dubious. If prt() doesn't return anything, a list
comprehension is useless. Functions only used as expressions shouldn't
have side-effects, like writing to stdout.

If you just need an a builtin function that writes to standard output,
you can use sys.stdout.write().

If you want a one-liner for your above example, something like this
looks better to me:

print "\n".join([str(x) for x in my_list])
[...] beforehand and any lambda construct would not be so handy. [...]
It should be a short one-liner. Any ideas?


It appears that you're suffering from the desease of neat-looking
one-liners.

I'll try to cure you at the next Stammtisch (local meeting of Pythoneers
at Munich) :-)

I tend to agree with the Effbot's favourite lambda refactoring rule:
http://mail.python.org/pipermail/pyt...il/036029.html ;)

-- Gerhard

Jul 18 '05 #6

P: n/a
Alex Martelli wrote:
Karl Scalet wrote:
...
>>sys.stdout.write("Hello world!\n")


I came across this, but this requires an extra import sys
which not always is there, thanks anyhow.

Ah, hadn't seen this before I answered your other post.

Well. duplicating the print statement functionality in
a *built-in* function to let you abuse a list comprehemsion
for the side effects and throw away the results just ain't
gonna happen. Built-in functions are (or should be: there
may well be purges in Python 3.0) just for tasks so important
and widespread that an 'import' cannot be considered.
Alex


Thank you for the answers.
I did not realize that taking only "the half of list comprehension"
is a misuse of it. That would mean list comprehension always "claim"
to be assigned to a variable. But why?
if i *had* a function doing any meaningful with the iterated values
by itstelf, why bother with the returned list.
Ex:
ignore = [ add_to_db(x) for x in my_list if x[:4]=='Hans']

Looks at least as nice to me as

for x in my_list:
if x[:4]=='Hans':
add_to_db(x)

But there might be reasons one prefers the for loop.

Back to my original desire:
I of course did not request to add a new funciton to
python built ins, I was just asking, if I miss a nice
idea to do the trick :-)

sys.stdout.write has the drawbacks:
- need to import sys, well....
- does no newline automatically, like print
- only handles strings

Again, no real pain all that :-)

Karl

Jul 18 '05 #7

P: n/a
Karl Scalet wrote:
...
Thank you for the answers.
You're welcome.
I did not realize that taking only "the half of list comprehension"
is a misuse of it. That would mean list comprehension always "claim"
to be assigned to a variable. But why?
Not really: any normal use of an expression is just as fine for a
list comprehension -- pass it as an argument, return it from a
function, use it as part of a larger expression (e.g. concatenate
several lists), and so on. Getting values to assigne to variables
is just one of the many normal ways in which you can use expressions,
and a list comprehension is an expression.

In languages which draw a distinction between expressions and
statements, and Python is in fact such a language, using an
expression purely for its side effects is normally best avoided,
because that's what statements are for. There are obvious corner
cases (since Python does not distinguish functions, which return
a value, from procedures, which only have side effects -- in a
language with the expression/statement distinction, it might be
conceptually cleaner to have the procedure/function one as well,
as in Pascal or Fortran, but Python follows C in having the
former but not the latter, drawing boundaries a bit differently),
but that is a reasonable general principle.
if i *had* a function doing any meaningful with the iterated values
by itstelf, why bother with the returned list.
Ex:
ignore = [ add_to_db(x) for x in my_list if x[:4]=='Hans']

Looks at least as nice to me as

for x in my_list:
if x[:4]=='Hans':
add_to_db(x)

But there might be reasons one prefers the for loop.
You should also consider other alternatives, such as:

for x in [ x for x in my_list if x.startswith('Hans') ]:
add_to_db(x)

(use .startswith, not [:4]==, for clarity & to avoid errors)
or even lambda-based ones (preferably with itertools):

for x in itertools.ifilter(lambda x: x.startswith('Hans'), my_list):
add_to_db(x)

The reason to avoid the list-comprehension is that a LC is a
construct that goes to quite some trouble to collect all the
results of the expression it starts with -- creates and
extends a list just for that, its MAIN purpose -- and when
you DON'T CARE about the MAIN purpose of a construct, using
it anyway is stretching things beyond clarity and legibility.

Want another example? Another side effect of a LC (in the
pursuit of its MAIN purpose -- creating a new list), besides
the one of looping, is binding the loop's control variable.
It's exceptional that way -- expressions normally don't
bind names... but a LC does. So, people desperate for a
close transcription of the C idiom

while((c=nauker())!=flip)
blaupas(c);

sometimes code "niceties" such as

while [c for c in [nauker()] if c!=flip]:
blaupas(c)

as the LC in the while's condition binds name 'c' as well
as giving the list (empty, i.e. false, at termination).
Of course, in this case Python offers a direct construct
to transliterate the idiom into:
for c in iter(nauker, flip):
blaupas(c)
but it's not so smooth when nauker takes args, or when the
form of the test is not of the "!=flip" kind.

Anyway, the principle is the same: a LC's main purpose is
to create a new list; therefore, use a LC when you want to
create a new list, but not when you don't care about said
list and only hanker for a side effect (the looping, or
the binding of control-variable names).

Back to my original desire:
I of course did not request to add a new funciton to
python built ins, I was just asking, if I miss a nice
idea to do the trick :-)

sys.stdout.write has the drawbacks:
- need to import sys, well....
- does no newline automatically, like print
- only handles strings

Again, no real pain all that :-)


Right: as I said, sys.stdout.write('%s\n'%x) is in fact
the equivalent, so the newline and stringification are
trivial issues, easily covered. If you want to avoid
a separate import statement at all costs, well, when
there's a will there's a way -- you CAN shoehorn it all
into a single longish expression...:

__import__('sys').stdout.write('%s\n' % x)

whether one would WANT that, of course, is another
issue;-).
Alex

Jul 18 '05 #8

P: n/a
Dnia Wed, 08 Oct 2003 12:22:12 +0200, Karl Scalet napisa³(a):
>import sys
>sys.stdout.write("Hello world!\n")


I came across this, but this requires an extra import sys
which not always is there, thanks anyhow.


It's ugly, but works:
[__import__('sys').stdout.write(str(i)+'\n') for i in range(5)]

or even:
[__import__('os').write(1, str(i)+'\n') for i in range(5)]

The main difference is that first will return an array of Nones
while the second will return an array of values returned by os.write().
Personally I prefer using print statement and join() method:

print '\n'.join([str(i) for i in range(5)])

--
[ Wojtek Walczak - gminick (at) underground.org.pl ]
[ <http://gminick.linuxsecurity.pl/> ]
[ "...rozmaite zwroty, matowe od patyny dawnosci." ]

Jul 18 '05 #9

P: n/a
Karl Scalet wrote:
Hi,

quite often there is a need to just print out the items of a list.

[ prt(x) for x in my_list ]

.....

Thank you all for the overwhelming sympathy to my original problem :-)

To clarify a bit:

I'm no fan of unreadable oneliners, normally, or making things more
complicated as they are.
I was just looking for the easiest way to *inspect*
*interactively* lists, dictionaries.
Evaluating such a list via
print my_list or even my_list does not give very readable results, especially if those
lists tend to become longer.

So my own (best??) solution is:
from pprint import pprint as prt # cannot overcome this line :-(
from qt import * # now the secret unveils
[ prt(x) for x in locals() if x[:2]=='QA' ] # sorry Signore Alex, but it's shorter than startswith :-)
# gives me 'QAssistantClient'
'QAccel'
'QActionGroup
'QApplication'
'QAction'
[None, None, None, None, None] # well, I can live with


In the case of doing such interactive inspections, i don't
mind about potential side-effects, i actually don't see them here.

Karl

PS:
I *did* write my own little helper functions for such things,
but then, you are in a different environment, and write the
helpis again and again.

Jul 18 '05 #10

P: n/a
Karl Scalet wrote:
So my own (best??) solution is:
from pprint import pprint as prt # cannot overcome this line :-(
from qt import * # now the secret unveils
[ prt(x) for x in locals() if x[:2]=='QA' ] # sorry Signore Alex, but it's shorter than startswith :-)
# gives me 'QAssistantClient'
'QAccel'
'QActionGroup
'QApplication'
'QAction'
[None, None, None, None, None] # well, I can live with


In the case of doing such interactive inspections, i don't
mind about potential side-effects, i actually don't see them here.


How about:

import qt
pprint.pprint(qt)

?

Gerrit.

--
138. If a man wishes to separate from his wife who has borne him no
children, he shall give her the amount of her purchase money and the dowry
which she brought from her father's house, and let her go.
-- 1780 BC, Hammurabi, Code of Law
--
Asperger Syndroom - een persoonlijke benadering:
http://people.nl.linux.org/~gerrit/
Kom in verzet tegen dit kabinet:
http://www.sp.nl/

Jul 18 '05 #11

P: n/a
Karl Scalet wrote:
Hi,

quite often there is a need to just print out the items of a list.

[ prt(x) for x in my_list ]

that would be nice, except prt() does not exist, and print is a
statement not a function, hence cannot replace prt as of above.

I don't like to write d
def prt(x):
print x
beforehand and any lambda construct would not be so handy.
It should be a short one-liner.
Any ideas?


import sys
sys.stdout.write("hello world\n")

HTH

Jul 18 '05 #12

P: n/a
Gerrit Holl wrote:
Karl Scalet wrote:
....
How about:

import qt
pprint.pprint(qt)

?
returns:
<module 'qt' from ....>

That's not the info i was for.
normal practice in qt-programming is from qt import *

now you can
pprint(locals()) as most of what's in this namespace now is
qt-related anyhow. But when it comes to
narrow down this list, as there are so
many items in it, I thougt using a list
comprehension with a condition would be
nice, even if I'm not longer sure after
all the responses :-).

For interactively inspecting things, I think
having it in one line is nice, as it's
easiest to recall from commandline history.

Which way?: [ pprint(x) for x in locals() if x[:3]=='QAc' ] or for x in locals():
if x[:3] == 'QAc':
print x


I cannot put this second one in a single line, so I
will stay with my list-comprehension-solution unless
I'm getting a better idea.

Karl

Jul 18 '05 #13

P: n/a
Heyho!

Karl Scalet wrote:
[...]
For interactively inspecting things, I think
having it in one line is nice, as it's
easiest to recall from commandline history.

Which way?:
>>> [ pprint(x) for x in locals() if x[:3]=='QAc' ] or >>> for x in locals():
>>> if x[:3] == 'QAc':
>>> print x


I cannot put this second one in a single line, so I
will stay with my list-comprehension-solution unless
I'm getting a better idea.

Karl


Why don't you wrap it in a function and put it in your
$PYTHONSTARTUP-file? That way you can call it very fast and don't need
to remember a one-liner.

Wolfram

Jul 18 '05 #14

P: n/a
Wolfram Kraus wrote:
Heyho!

Karl Scalet wrote:
[...]
For interactively inspecting things, I think
having it in one line is nice, as it's
easiest to recall from commandline history.

Which way?:
>>> [ pprint(x) for x in locals() if x[:3]=='QAc' ]

or
>>> for x in locals():
>>> if x[:3] == 'QAc':
>>> print x


I cannot put this second one in a single line, so I
will stay with my list-comprehension-solution unless
I'm getting a better idea.

Karl


Why don't you wrap it in a function and put it in your
$PYTHONSTARTUP-file? That way you can call it very fast and don't need
to remember a one-liner.

Wolfram


Hello Wolfram,

you're right, that would be best. I myself however always end up
not having all the helper functions available after a while, working
in different environments. But that's more an organizational problem:-)

Thanks anyhow,
Karl

Jul 18 '05 #15

P: n/a
On Wed, 08 Oct 2003 11:32:20 +0200, Karl Scalet <ne**@yebu.de> wrote:
Hi,

quite often there is a need to just print out the items of a list.
[ prt(x) for x in my_list ]

that would be nice, except prt() does not exist, and print is a
statement not a function, hence cannot replace prt as of above.

I don't like to write d
def prt(x):
print x
beforehand and any lambda construct would not be so handy.
It should be a short one-liner.
Any ideas?


what's wrong with the straightforward suggestion elsewhere in the thread? I.e.,

for x in my_list: print x

Unless you don't like the many calls to sys.stdout.write that are generated
by that for loop. You can make it into a single write with

sys.stdout.write('\n'.join(my_list+['']))

But if all your pieces already have newlines, or you just want to concatenate strings
to stdout, note:
import sys
help(sys.stdout.writelines) """
Help on built-in function writelines:

writelines(...)
writelines(sequence_of_strings) -> None. Write the strings to the file.

Note that newlines are not added. The sequence can be any iterable object
producing strings. This is equivalent to calling write() for each string.
""" sys.stdout.writelines(['<<=starts here,\n','and this is 2nd line\n',

... '3rd - no ending newline:', '<<-missing new line\n',
... 'last line\n'])
<<=starts here,
and this is 2nd line
3rd - no ending newline:<<-missing new line
last line

Regards,
Bengt Richter
Jul 18 '05 #16

P: n/a
Bengt Richter wrote:
On Wed, 08 Oct 2003 11:32:20 +0200, Karl Scalet <ne**@yebu.de> wrote:

what's wrong with the straightforward suggestion elsewhere in the thread? I.e.,

for x in my_list: print x

I am yet convinced, this is the best solution for printing a simple list
Unless you don't like the many calls to sys.stdout.write that are generated
by that for loop. You can make it into a single write with

sys.stdout.write('\n'.join(my_list+['']))
I like that as well, but as of performance wasn't the issue, the first
solution is easier anyhow.

But if all your pieces already have newlines, or you just want to concatenate strings
to stdout, note:


Unfortunately the items in the list do not end in newlines,
nevertheless, thanks for pointing out writelines.

But what, if I have a condition on the list.
Everyone tries to keep me away from list-comprehension :-)

But I do not have a better/easier_to_type solution to

[sys.stdout.write_whatsoever(x) for x in my_list if x.i_am_good_one()]
# x having a __str__ in that case :-)

Maybe I do not understand potential problems from side-effects, which
I do not see in *this* case.

Yours insisting-ly,

Karl

Jul 18 '05 #17

P: n/a
On Wed, 08 Oct 2003 12:27:06 GMT, Alex Martelli <al***@aleax.it> wrote:
[...]

Right: as I said, sys.stdout.write('%s\n'%x) is in fact
the equivalent, so the newline and stringification are
trivial issues, easily covered. If you want to avoid
a separate import statement at all costs, well, when
there's a will there's a way -- you CAN shoehorn it all
into a single longish expression...:

__import__('sys').stdout.write('%s\n' % x)

whether one would WANT that, of course, is another
issue;-).


Plus, the side effect to sys.modules will still happen, e.g.,:
import sys
'math' in sys.modules False twopi = __import__('math').pi*2.0
twopi 6.2831853071795862 'math' in sys.modules True

Anyway, with a little rearrangement, he could have his prt with most of the work built in once:
prt = (lambda w,x: w('%s\n'%x)).__get__(__import__('sys').stdout.writ e)
prt('Hello');prt('Next line') Hello
Next line

or a version for selected expression item side effect output: prt = (lambda w,x: w('%s\n'%x) or x).__get__(__import__('sys').stdout.write)
prt('Hello'),prt('Next line') Hello
Next line
('Hello', 'Next line') print 'expr value = %r' % (2*prt(3)*4,) 3
expr value = 24

Hm, if that were conditional, it could have debug print use...
prt = (lambda w,x,p=lambda x:False: p(x) and w('<%s>'%x) and 0 or x).__get__(__import__('sys ').stdout.write)
pcond = lambda x: x in (2,5,11,17)

for i in range(21): print prt(i,pcond), ...
0 1<2>2 3 4<5>5 6 7 8 9 10<11>11 12 13 14 15 16<17>17 18 19 20

This is getting silly with the lambdas though,
class Prt(object): ... wrso = __import__('sys').stdout.write
... def __init__(self, pcond=lambda x:False, fmt='%s\n'):
... self.pcond=pcond; self.fmt=fmt
... def __call__(self, x):
... if self.pcond(x): self.wrso(self.fmt%x)
... return x
... prt = Prt()
for i in range(21): print prt(i), ...
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 prt = Prt(pcond, '<!--\n%r discovered\n-->')
for i in range(21): print prt(i),

...
0 1<!--
2 discovered
-->2 3 4<!--
5 discovered
-->5 6 7 8 9 10<!--
11 discovered
-->11 12 13 14 15 16<!--
17 discovered
-->17 18 19 20

(BTW, in my other post I forgot to take into account that the OP's list of things
to print might not all be string items).

(Not really replying to your post, Alex, just ramblings triggered by it ;-)

Regards,
Bengt Richter
Jul 18 '05 #18

P: n/a
On Wed, 8 Oct 2003 13:56:51 +0000 (UTC), Wojtek Walczak <gm*****@hacker.pl> wrote:
Dnia Wed, 08 Oct 2003 12:22:12 +0200, Karl Scalet napisa³(a):
>>import sys
>>sys.stdout.write("Hello world!\n")


I came across this, but this requires an extra import sys
which not always is there, thanks anyhow.


It's ugly, but works:
[__import__('sys').stdout.write(str(i)+'\n') for i in range(5)]

or even:
[__import__('os').write(1, str(i)+'\n') for i in range(5)]

The main difference is that first will return an array of Nones
while the second will return an array of values returned by os.write().
Personally I prefer using print statement and join() method:

print '\n'.join([str(i) for i in range(5)])

Not that I am advocating list comprehension abuse for other than amusement and edification,
but you can avoid building a list of Nones and the repeated imports by rearranging things, e.g.,
[__import__('sys').stdout.write(str(i)+'\n') for i in range(5)] 0
1
2
3
4
[None, None, None, None, None] [0 for w in [__import__('sys').stdout.write] for i in range(5) if w(str(i)+'\n')] 0
1
2
3
4
[]

You can hide the [] from the interactive result printout too: [0 for w in [__import__('sys').stdout.write] for i in range(5) if w(str(i)+'\n')] or None 0
1
2
3
4

But it's kind of silly to keep typing stuff like that when you can just collect little utility
goodies in a module and import them for interactive use, e.g.,
from ut.miscutil import pl, prb
pl(map(str, range(50)), 10)
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49 prb(0xfa)

'11111010'

Regards,
Bengt Richter
Jul 18 '05 #19

P: n/a
On Wed, 08 Oct 2003 17:15:30 +0200, Karl Scalet <ne**@yebu.de> wrote:
Karl Scalet wrote:
Hi,

quite often there is a need to just print out the items of a list.

[ prt(x) for x in my_list ]
....

Thank you all for the overwhelming sympathy to my original problem :-)

To clarify a bit:

I'm no fan of unreadable oneliners, normally, or making things more
complicated as they are.
I was just looking for the easiest way to *inspect*
*interactively* lists, dictionaries.
Evaluating such a list via
print my_listor even my_listdoes not give very readable results, especially if those
lists tend to become longer.

So my own (best??) solution is:
from pprint import pprint as prt # cannot overcome this line :-(
from qt import * # now the secret unveils
[ prt(x) for x in locals() if x[:2]=='QA' ]# sorry Signore Alex, but it's shorter than startswith :-)
# gives me 'QAssistantClient'
'QAccel'
'QActionGroup
'QApplication'
'QAction'
[None, None, None, None, None] # well, I can live with You don't have to, if you write (untested)

[0 for x in locals() if x[:2]=='QA' and prt(x)] or None

or if you make a prt that can return other than None, you can guarantee the
if failure by writing

[0 for x in locals() if x[:2]=='QA' and prt(x) and 0] or None
In the case of doing such interactive inspections, i don't
mind about potential side-effects, i actually don't see them here.

Interactively, UIAM for some case, locals()==globals(), so if you want to
avoid typing that more than once, you might want to make a function, e.g. (untested)

pqa = lambda:[0 for x in globals() if x[:2]=='QA' and prt(x)] or None

and then just type pqa()

But a better idea is to code yourself some simple utility functions in the most
straightforward way, with simple doc strings, and put them in a module that you can
import from, and check on what you did, e.g., I don't always take my own advice, but
from ut.miscutil import pl
help(pl)

Help on function pl in module ut.miscutil:

pl(alist, cols=None, width=78)
prints a list one left-justified item per line
or in cols columns across width(default 78)

For almost-throwaways relating only to a particular project, just accumulate them
in e.g., goodies.py in the same directory, and you can interactively type

from goodies import *

and be ready to go.

Regards,
Bengt Richter
Jul 18 '05 #20

This discussion thread is closed

Replies have been disabled for this discussion.