1

I'm trying to print a simple table in python, but none of the previous answers seem to be exactly what I'm looking for. Any and all help would be greatly appreciated.

I have a list (of texts):

texts = [caesar,hamlet,macbeth,emma,persuasion,sense]

I then run a function called 'similarity,' which compares 2 texts. I'd like to print the results in a table, but I can't seem to get a new line after the print statement has iterated through one loop of the list. [Note: I'm using Python 2.6.6, because I'm using Natural Language Toolkit, a python module for linguistics.]

Here is my current print statement, which does not work correctly:

for x in texts:
    for y in texts:
        print round(similarity(x,y),2),
        if texts.index(x) == len(texts):
            print '\n'

Any pointers in the right direction would be great!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Adam_G
  • 7,337
  • 20
  • 86
  • 148

4 Answers4

2

The process of comparing each item in a list with each item in (another or the same) list is mathematically known as a Cartesian product. Python has a built-in function to do this: itertools.product which is equivalent to nested for-loops:

Suppose A and B are lists:

for x in A:
    for y in B:
        print (x,y)

can be written with a generator expression as:

for pair in ((x,y) for x in A for y in B):
    print pair

or, more succinctly:

from itertools import product
for pair in product(A, B):
    print pair

In your case you're comparing all the items of a list to itself, so you could write product(texts, texts), but product has the optional keyword argument repeat for this case: product(A, repeat=4) means the same as product(A, A, A, A).

You could rewrite your code now like this:

from itertools import product

caesar = """BOOK I
I.--All Gaul is divided into three parts, one of which the Belgae
inhabit, the Aquitani another, those who in their own language are
called Celts, in ours Gauls, the third. All these differ from each other
in language, customs and laws."""

hamlet = """Who's there?" 
"Nay, answer me. Stand and unfold yourself." 
"Long live the King!" 
"Barnardo!" 
"He." (I.i.1-5)"""

macbeth = """ACT I  SCENE I     A desert place. Thunder and lightning.   
[Thunder and lightning. Enter three Witches]
First Witch When shall we three meet again
In thunder, lightning, or in rain?
Second Witch    When the hurlyburly's done,
When the battle's lost and won."""

texts = [caesar, hamlet, macbeth]

def similarity(x, y):
    """similarity based on length of the text,
    substitute with similarity function from Natural Language Toolkit"""
    return float(len(x))/len(y)


for pair in product(texts, repeat=2):
    print "{}".format(similarity(*pair))
BioGeek
  • 21,897
  • 23
  • 83
  • 145
1

Simply move printing the new-line to the outer loop:

for x in texts:
    for y in texts:
        print "{:8.2f}".format(similarity(x,y)),
    print

A bare print statement will print a line break. Also note that round() isn't meant to be used for string formatting -- use str.format() instead.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • Thanks so much. I really appreciate it! I'm using round(), because my similarity() function outputs a float. – Adam_G Feb 28 '12 at 14:48
  • @Adam_G: I know why you are using `round()`, but as said above, `round()` is not meant to be used for output formatting. See the section [Fancier Output Formatting](http://docs.python.org/tutorial/inputoutput.html#fancier-output-formatting) from the Python Tutorial for more information on output formatting, and see the section [Floating Point Arithmetic: Issues and Limitations](http://docs.python.org/tutorial/floatingpoint.html) why it is a bad idea to use `round()` for this purpose. – Sven Marnach Feb 28 '12 at 14:55
1

Just use print on a line of its own.

Also, why aren't you doing something like this?

for x in texts:
    for y in texts:
        print round(similarity(x,y),2),
    print
cha0site
  • 10,517
  • 3
  • 33
  • 51
0

Try out my library TableIt

NOTE: This answer is already posted on this question.

I just made a library for this that I think could really help. It is extremely simple, that's why I think you should use it. It is called TableIT.

Basic Use

To use it, first follow the download instructions on the GitHub Page.

Then import it:

import TableIt

Then make a list of lists where each inner list is a row:

table = [
    [4, 3, "Hi"],
    [2, 1, 808890312093],
    [5, "Hi", "Bye"]
]

Then all you have to do is print it:

TableIt.printTable(table)

This is the output you get:

+--------------------------------------------+
| 4            | 3            | Hi           |
| 2            | 1            | 808890312093 |
| 5            | Hi           | Bye          |
+--------------------------------------------+

Field Names

You can use field names if you want to (if you aren't using field names you don't have to say useFieldNames=False because it is set to that by default):


TableIt.printTable(table, useFieldNames=True)

From that you will get:

+--------------------------------------------+
| 4            | 3            | Hi           |
+--------------+--------------+--------------+
| 2            | 1            | 808890312093 |
| 5            | Hi           | Bye          |
+--------------------------------------------+

There are other uses to, for example you could do this:

import TableIt

myList = [
    ["Name", "Email"],
    ["Richard", "richard@fakeemail.com"],
    ["Tasha", "tash@fakeemail.com"]
]

TableIt.print(myList, useFieldNames=True)

From that:

+-----------------------------------------------+
| Name                  | Email                 |
+-----------------------+-----------------------+
| Richard               | richard@fakeemail.com |
| Tasha                 | tash@fakeemail.com    |
+-----------------------------------------------+

Or you could do:

import TableIt

myList = [
    ["", "a", "b"],
    ["x", "a + x", "a + b"],
    ["z", "a + z", "z + b"]
]

TableIt.printTable(myList, useFieldNames=True)

And from that you get:

+-----------------------+
|       | a     | b     |
+-------+-------+-------+
| x     | a + x | a + b |
| z     | a + z | z + b |
+-----------------------+

Colors

You can also use colors.

You use colors by using the color option (by default it is set to None) and specifying RGB values.

Using the example from above:

import TableIt

myList = [
    ["", "a", "b"],
    ["x", "a + x", "a + b"],
    ["z", "a + z", "z + b"]
]

TableIt.printTable(myList, useFieldNames=True, color=(26, 156, 171))

Then you will get:

enter image description here

Please note that printing colors might not work for you but it does works the exact same as the other libraries that print colored text. I have tested and every single color works. The blue is not messed up either as it would if using the default 34m ANSI escape sequence (if you don't know what that is it doesn't matter). Anyway, it all comes from the fact that every color is RGB value rather than a system default.

More Info

For more info check the GitHub Page

BeastCoder
  • 2,391
  • 3
  • 15
  • 26