2013-06-05 4 views
7

मेरे पास ऊपरी मामले में कॉलम नामों के साथ एक CSV फ़ाइल है। मैं csv.dictreader का उपयोग कर डेटा पढ़ रहा हूं लेकिन लोअरकेस में कॉलम नामों की आवश्यकता है।पायथन dictreader - सीएसवी कॉलम नाम लोअरकेस कैसे बनाएं?

मैंने पाया इस कोड को यहाँ Accessing csv header white space and case insensitive

import csv 

class DictReaderInsensitive(csv.DictReader): 
    # This class overrides the csv.fieldnames property. 
    # All fieldnames are without white space and in lower case 

    @property 
    def fieldnames(self): 
     return [field.strip().lower() for field in super(DictReaderInsensitive, self).fieldnames] 

    def __next__(self): 
     # get the result from the original __next__, but store it in DictInsensitive 

     dInsensitive = DictInsensitive() 
     dOriginal = super(DictReaderInsensitive, self).__next__() 

     # store all pairs from the old dict in the new, custom one 
     for key, value in dOriginal.items(): 
      dInsensitive[key] = value 

     return dInsensitive 

class DictInsensitive(dict): 
    # This class overrides the __getitem__ method to automatically strip() and lower() the input key 

    def __getitem__(self, key): 
     return dict.__getitem__(self, key.strip().lower()) 

मेरे समस्या यह है कि मैं यह त्रुटि

Traceback (most recent call last): 
    File "D:\Development\python\supplier_review\supplier_review.py", line 239, in update_ifs_data 
    for row in csvDict: 
    File "D:\Python27_5\lib\csv.py", line 103, in next 
    self.fieldnames 
    File "D:\Development\python\supplier_review\supplier_review.py", line 288, in fieldnames 
    return [field.strip().lower() for field in super(DictReaderInsensitive, self).fieldnames] 
TypeError: must be type, not classobj 

उत्तर

7

DictReader मिलता है जब मैं

datafile = open(self.ifs_data_file,'rU') 
     csvDict = DictReaderInsensitive(datafile) 
     for row in csvDict: 
      print row 
      #self.db.ifs_data.insert(**row) 
      #self.db.commit() 

के साथ इस चलाया जाता है एक पुरानी शैली है ऑब्जेक्ट, तो super() यहां बिल्कुल काम नहीं करता है। आपको मूल कक्षा में सीधे property ऑब्जेक्ट तक पहुंचने की आवश्यकता है।

class DictReaderInsensitive(csv.DictReader): 
    # This class overrides the csv.fieldnames property. 
    # All fieldnames are without white space and in lower case 

    @property 
    def fieldnames(self): 
     return [field.strip().lower() for field in csv.DictReader.fieldnames.fget(self)] 

    def next(self): 
     return DictInsensitive(csv.DictReader.next(self)) 

डेमो::

>>> example = '''\ 
... foo,Bar,BAZ 
... 42,3.14159,Hello world!'''.splitlines() 
>>> csvDict = DictReaderInsensitive(example) 
>>> row = next(csvDict) 
>>> print row 
{'bar': '3.14159', 'foo': '42', 'baz': 'Hello world!'} 
>>> row['BAZ'] 
'Hello world!' 
+0

आपके सुझावों के लिए आप दोनों को धन्यवाद। मुझे इस समस्या के आसपास एक और रास्ता मिला लेकिन ईमानदार होने के लिए मुझे याद नहीं आया कि यह क्या था। मैंने मार्टिजन की कोशिश की लेकिन यह मेरे लिए काम नहीं किया। – PrestonDocks

+2

मुझे खेद है कि मेरा समाधान आपके लिए काम नहीं करता है; क्या आपने मुझे बताया कि आपको किस समस्या का सामना करना पड़ा था, शायद मैं उन्हें दूर करने में आपकी मदद कर सकता था। जैसा कि आप मेरे उत्तर से देख सकते हैं मैंने आपके लिए कोड का परीक्षण किया। –

5

आप इसे DictReader को पार करने से पहले फ़ाइल की पहली पंक्ति लोअरकेस सकता है:

import csv 
import itertools 

def lower_first(iterator): 
    return itertools.chain([next(iterator).lower()], iterator) 

with open(ifs_data_file, 'rU') as datafile: 
    csvDict = csv.DictReader(lower_first(datafile)) 
    for row in csvDict: 
     print row  
अजगर 2 में, आप .next() विधि, नहीं .__next__() ओवरराइड करना चाहते
+0

चार साल बाद, यह अभी भी एक उपयोगी, आसान कार्यान्वित तकनीक है। – scottwed

2

एक बहुत ही सरल दृष्टिकोण के लिए, आप बस अपने शब्दकोश तक पहुंचने से पहले DictReader.fieldnames विशेषता को अपडेट कर सकते हैं, जैसे:

>>> f = open('example-x-y-time.csv', 'rb') 
>>> reader = csv.DictReader(f) 
>>> reader.fieldnames 
['Latitude', 'Longitude', 'Date'] 
>>> print next(reader) 
{'Latitude': '44.8982391', 'Date': '2004-07-12', 'Longitude': '-117.7791061'} 
>>> reader.fieldnames = [name.lower() for name in reader.fieldnames] 
>>> print next(reader) 
{'latitude': '44.6637001', 'date': '1964-04-03', 'longitude': '-123.5997009'} 
संबंधित मुद्दे