@@ -518,24 +518,33 @@ def _normalize_tabular_data(tabular_data, headers):
518
518
elif (headers == "keys"
519
519
and len (rows ) > 0
520
520
and isinstance (rows [0 ], tuple )
521
- and hasattr (rows [0 ], "_fields" )): # namedtuple
521
+ and hasattr (rows [0 ], "_fields" )):
522
+ # namedtuple
522
523
headers = list (map (_text_type , rows [0 ]._fields ))
523
524
elif (len (rows ) > 0
524
525
and isinstance (rows [0 ], dict )):
525
- # works for dict and OrderedDict
526
- mmap = {} # implements hashed lookup
526
+ # dict or OrderedDict
527
+ uniq_keys = set () # implements hashed lookup
527
528
keys = [] # storage for set
528
- for row in rows :
529
+ if headers == "firstrow" :
530
+ firstdict = rows [0 ] if len (rows ) > 0 else {}
531
+ keys .extend (firstdict .keys ())
532
+ uniq_keys .update (keys )
533
+ rows = rows [1 :]
534
+ for row in rows :
529
535
for k in row .keys ():
530
536
#Save unique items in input order
531
- if k not in mmap :
532
- mmap [k ] = 1
537
+ if k not in uniq_keys :
533
538
keys .append (k )
534
- keys = list (map (_text_type , keys ))
535
- rows = [[row .get (k ) for k in keys ] for row in rows ]
536
- if headers == 'keys' :
539
+ uniq_keys .add (k )
540
+ if headers == 'keys' :
537
541
headers = keys
538
- elif headers == "keys" and len (rows ) > 0 : # keys are column indices
542
+ elif headers == "firstrow" and len (rows ) > 0 :
543
+ headers = [firstdict .get (k , k ) for k in keys ]
544
+ headers = list (map (_text_type , headers ))
545
+ rows = [[row .get (k ) for k in keys ] for row in rows ]
546
+ elif headers == "keys" and len (rows ) > 0 :
547
+ # keys are column indices
539
548
headers = list (map (_text_type , range (len (rows [0 ]))))
540
549
541
550
# take headers from the first row if necessary
0 commit comments