【问题标题】:python csv, writing headers only oncepython csv,只写一次标题
【发布时间】:2015-04-04 05:24:40
【问题描述】:

所以我有一个从 .Json 创建 CSV 的程序。

首先我加载 json 文件。

f = open('Data.json')
data = json.load(f)
f.close()

然后我会遍历它,寻找一个特定的关键字,如果我找到那个关键字的话。我会将与此相关的所有内容都写在 .csv 文件中。

for item in data:
    if "light" in item:
       write_light_csv('light.csv', item)

这是我的write_light_csv 函数:

def write_light_csv(filename,dic):

    with open (filename,'a') as csvfile:
        headers = ['TimeStamp', 'light','Proximity']
        writer = csv.DictWriter(csvfile, delimiter=',', lineterminator='\n',fieldnames=headers)

        writer.writeheader()

        writer.writerow({'TimeStamp': dic['ts'], 'light' : dic['light'],'Proximity' : dic['prox']})

我最初使用wb+ 作为模式,但是每次打开文件进行写入时都会清除所有内容。我用a 替换了它,现在每次写入时,它都会添加一个标题。如何确保标头只写一次?

【问题讨论】:

    标签: python csv


    【解决方案1】:

    您可以检查文件是否已经存在,然后不要调用writeheader(),因为您正在使用附加选项打开文件。

    类似的东西:

    import os.path
    
    
    file_exists = os.path.isfile(filename)
    
    with open (filename, 'a') as csvfile:
        headers = ['TimeStamp', 'light', 'Proximity']
        writer = csv.DictWriter(csvfile, delimiter=',', lineterminator='\n',fieldnames=headers)
    
        if not file_exists:
            writer.writeheader()  # file doesn't exist yet, write a header
    
        writer.writerow({'TimeStamp': dic['ts'], 'light': dic['light'], 'Proximity': dic['prox']})
    

    【讨论】:

    • @Kos 在with 块中没有对文件对象进行任何操作之前,该文件不会被写入磁盘,但你是对的,这有点令人困惑。我改变了我的例子。
    • @Kos 对不起,你是对的,文件是较早创建的。
    • @igor,file_exists 行有错字,你不需要那个冒号 :)
    • @IgorHatarist 非常感谢!
    • 非常感谢,真的解决了我的问题
    【解决方案2】:

    你能改变你的代码结构并一次导出整个文件吗?

    def write_light_csv(filename, data):
        with open (filename, 'w') as csvfile:
            headers = ['TimeStamp', 'light','Proximity']
            writer = csv.DictWriter(csvfile, delimiter=',', lineterminator='\n',fieldnames=headers)
    
            writer.writeheader()
    
            for item in data:
                if "light" in item:
                    writer.writerow({'TimeStamp': item['ts'], 'light' : item['light'],'Proximity' : item['prox']})
    
    
    write_light_csv('light.csv', data)
    

    【讨论】:

      【解决方案3】:

      我会使用一些flag 并在写headers 之前运行检查!例如

      flag=0
      def get_data(lst):
          for i in lst:#say list of url
              global flag
              respons = requests.get(i)
              respons= respons.content.encode('utf-8')
              respons=respons.replace('\\','')
              print respons
              data = json.loads(respons)
              fl = codecs.open(r"C:\Users\TEST\Desktop\data1.txt",'ab',encoding='utf-8')
              writer = csv.DictWriter(fl,data.keys())
              if flag==0:
                  writer.writeheader()
              writer.writerow(data)
              flag+=1
              print "You have written % times"%(str(flag))
          fl.close()
      get_data(urls)
      

      【讨论】:

        【解决方案4】:

        你可以检查文件是否为空

        import csv
        import os
        
        headers = ['head1', 'head2']
        
        for row in interator:
            with open('file.csv', 'a') as f:
                file_is_empty = os.stat('file.csv').st_size == 0
                writer = csv.writer(f, lineterminator='\n')
                if file_is_empty:
                    writer.writerow(headers)
                writer.writerow(row)
        

        【讨论】:

          【解决方案5】:

          只是另一种方式:

          with open(file_path, 'a') as file:
                  w = csv.DictWriter(file, my_dict.keys())
          
                  if file.tell() == 0:
                      w.writeheader()
          
                  w.writerow(my_dict)
          

          【讨论】:

            【解决方案6】:

            您可以使用csv.Sniffer 类和

            with open('my.csv', newline='') as csvfile:
                if csv.Sniffer().has_header(csvfile.read(1024))
                # skip writing headers
            

            【讨论】:

              【解决方案7】:

              使用 Pandas 时:(用于将 Dataframe 数据存储到 CSV 文件) 如果您使用索引来迭代 API 调用以在 CSV 文件中添加数据,只需在设置标头属性之前添加此检查。

              if i > 0:
                      dataset.to_csv('file_name.csv',index=False, mode='a', header=False)
                  else:
                      dataset.to_csv('file_name.csv',index=False, mode='a', header=True)
              

              【讨论】:

                【解决方案8】:

                这是另一个仅依赖于 Python 的内置 csv 包的示例。此方法检查标头是否符合预期或引发错误。它还通过写入标题来处理文件不存在或确实存在但为空的情况。希望这会有所帮助:

                import csv
                import os
                
                
                def append_to_csv(path, fieldnames, rows):
                    is_write_header = not os.path.exists(path) or _is_empty_file(path)
                    if not is_write_header:
                        _assert_field_names_match(path, fieldnames)
                
                    _append_to_csv(path, fieldnames, rows, is_write_header)
                
                
                def _is_empty_file(path):
                    return os.stat(path).st_size == 0
                
                
                def _assert_field_names_match(path, fieldnames):
                    with open(path, 'r') as f:
                        reader = csv.reader(f)
                        header = next(reader)
                        if header != fieldnames:
                            raise ValueError(f'Incompatible header: expected {fieldnames}, '
                                             f'but existing file has {header}')
                
                
                def _append_to_csv(path, fieldnames, rows, is_write_header: bool):
                    with open(path, 'a') as f:
                        writer = csv.DictWriter(f, fieldnames=fieldnames)
                        if is_write_header:
                            writer.writeheader()
                        writer.writerows(rows)
                
                

                您可以使用以下代码对此进行测试:

                
                file_ = 'countries.csv'
                fieldnames_ = ['name', 'area', 'country_code2', 'country_code3']
                rows_ = [
                    {'name': 'Albania', 'area': 28748, 'country_code2': 'AL', 'country_code3': 'ALB'},
                    {'name': 'Algeria', 'area': 2381741, 'country_code2': 'DZ', 'country_code3': 'DZA'},
                    {'name': 'American Samoa', 'area': 199, 'country_code2': 'AS', 'country_code3': 'ASM'}
                ]
                
                append_to_csv(file_, fieldnames_, rows_)
                
                

                如果你在countries.csv 中得到以下信息后运行它:

                name,area,country_code2,country_code3
                Albania,28748,AL,ALB
                Algeria,2381741,DZ,DZA
                American Samoa,199,AS,ASM
                

                如果你运行两次,你会得到以下信息(注意,没有第二个标题):

                name,area,country_code2,country_code3
                Albania,28748,AL,ALB
                Algeria,2381741,DZ,DZA
                American Samoa,199,AS,ASM
                Albania,28748,AL,ALB
                Algeria,2381741,DZ,DZA
                American Samoa,199,AS,ASM
                

                如果你随后更改countries.csv 中的标题并再次运行程序,你将得到一个值错误,如下所示:

                ValueError: Incompatible header: expected ['name', 'area', 'country_code2', 'country_code3'], but existing file has ['not', 'right', 'fieldnames']
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2021-07-19
                  • 2018-12-23
                  • 2016-11-16
                  • 1970-01-01
                  • 2018-05-15
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-10-17
                  相关资源
                  最近更新 更多