@@ -598,7 +598,7 @@ def _align_header(header, alignment, width):
598
598
return _padleft (width , header )
599
599
600
600
601
- def _normalize_tabular_data (tabular_data , headers ):
601
+ def _normalize_tabular_data (tabular_data , headers , index = None ):
602
602
"""Transform a supported data type to a list of lists, and a list of headers.
603
603
604
604
Supported tabular data types:
@@ -634,8 +634,10 @@ def _normalize_tabular_data(tabular_data, headers):
634
634
# values is a property, has .index => it's likely a pandas.DataFrame (pandas 0.11.0)
635
635
keys = tabular_data .keys ()
636
636
vals = tabular_data .values # values matrix doesn't need to be transposed
637
- names = tabular_data .index
638
- rows = [[v ]+ list (row ) for v ,row in zip (names , vals )]
637
+ # For DataFrames add an index per default
638
+ if index in [None , True ]:
639
+ index = tabular_data .index
640
+ rows = [list (row ) for row in vals ]
639
641
else :
640
642
raise ValueError ("tabular data doesn't appear to be a dict or a DataFrame" )
641
643
@@ -687,6 +689,7 @@ def _normalize_tabular_data(tabular_data, headers):
687
689
elif headers :
688
690
raise ValueError ('headers for a list of dicts is not a dict or a keyword' )
689
691
rows = [[row .get (k ) for k in keys ] for row in rows ]
692
+
690
693
elif headers == "keys" and len (rows ) > 0 :
691
694
# keys are column indices
692
695
headers = list (map (_text_type , range (len (rows [0 ]))))
@@ -696,6 +699,18 @@ def _normalize_tabular_data(tabular_data, headers):
696
699
headers = list (map (_text_type , rows [0 ])) # headers should be strings
697
700
rows = rows [1 :]
698
701
702
+ # Add an index column, either from a supplied list of index values or from the dataframe index
703
+ # or simple a running count if index==True
704
+ if index :
705
+ if index is True :
706
+ index = range (len (rows ))
707
+ elif index :
708
+ index = list (index )
709
+ if len (index ) != len (rows ):
710
+ raise ValueError ('index must be as long as the rows (excluding a header row if '
711
+ '"headers=firstrow"' )
712
+ rows = [[v ]+ list (row ) for v ,row in zip (index , rows )]
713
+
699
714
headers = list (map (_text_type ,headers ))
700
715
rows = list (map (list ,rows ))
701
716
@@ -711,7 +726,7 @@ def _normalize_tabular_data(tabular_data, headers):
711
726
712
727
def tabulate (tabular_data , headers = (), tablefmt = "simple" ,
713
728
floatfmt = "g" , numalign = "decimal" , stralign = "left" ,
714
- missingval = "" ):
729
+ missingval = "" , index = None ):
715
730
"""Format a fixed width table for pretty printing.
716
731
717
732
>>> print(tabulate([[1, 2.34], [-56, "8.999"], ["2", "10001"]]))
@@ -743,6 +758,11 @@ def tabulate(tabular_data, headers=(), tablefmt="simple",
743
758
are supposed to be names of the last columns. This is consistent
744
759
with the plain-text format of R and Pandas' dataframes.
745
760
761
+ If `index=True` or if `tabular_data` is a pandas.DataFrame, a column with
762
+ a row count or the index of the dataframe is shown. `index=False` does not
763
+ show an index. If `index` is an iterable, this value is used as the index
764
+ row (must be as long as the number of rows).
765
+
746
766
>>> print(tabulate([["sex","age"],["Alice","F",24],["Bob","M",19]],
747
767
... headers="firstrow"))
748
768
sex age
@@ -946,7 +966,8 @@ def tabulate(tabular_data, headers=(), tablefmt="simple",
946
966
"""
947
967
if tabular_data is None :
948
968
tabular_data = []
949
- list_of_lists , headers = _normalize_tabular_data (tabular_data , headers )
969
+ list_of_lists , headers = _normalize_tabular_data (tabular_data , headers ,
970
+ index = index )
950
971
951
972
# optimization: look for ANSI control codes once,
952
973
# enable smart width functions only if a control code is found
0 commit comments