python - the - هل من الممكن الحفاظ على ترتيب الأعمدة باستخدام csv.DictReader؟



csv viewer (4)

على سبيل المثال ، تحتوي csv على أعمدة كما يلي:

ID, ID2, Date, Job No, Code

أحتاج إلى كتابة الأعمدة مرة أخرى بنفس الترتيب. إن الأمر يخلط الأمر على الفور ، لذا أعتقد أنه مشكلة مع القارئ.

https://src-bin.com


Answer #1

أعرف أن هذا السؤال قديم ... ولكن إذا كنت تستخدم DictReader ، فيمكنك تمرير قائمة مرتبة مع DictReader


Answer #2

جعل OrderedDict من كل صف مرتبة حسب DictReader.fieldnames .

import csv
from collections import OrderedDict

reader = csv.DictReader(open("file.csv"))
for row in reader:
    sorted_row = OrderedDict(sorted(row.items(),
          key=lambda item: reader.fieldnames.index(item[0])))

Answer #3

لم تحافظ أوامر Python s على النظام قبل 3.6 (ولكن ، بغض النظر ، في هذا الإصدار تم تعديل فئة OrderedDict لإرجاع OrderedDict s).

ومع ذلك ، فإن مثيل csv.DictReader الذي تستخدمه (بعد قراءة الصف الأول! -) يحتوي على قائمة .fieldnames ، وهي IS بالترتيب.

وبالتالي،

for rowdict in myReader:
  print ['%s:%s' % (f, rowdict[f]) for f in myReader.fieldnames]

سوف تظهر لك أنه تم الحفاظ على الترتيب بالفعل (في .fieldnames بالطبع ، أبدا في dict - وهذا مستحيل جوهريا في بايثون! -).

لذلك ، لنفترض أنك تريد قراءة a.csv وكتابة b.csv بنفس ترتيب الأعمدة. استخدام القارئ العادي والكاتب سهل جدا ، لذلك كنت ترغب في استخدام أصناف Dict بدلا من ذلك ؛-). حسنًا ، إحدى الطرق هي ...:

import csv

a = open('a.csv', 'r')
b = open('b.csv', 'w')
ra = csv.DictReader(a)
wb = csv.DictWriter(b, None)

for d in ra:

  if wb.fieldnames is None:
    # initialize and write b's headers
    dh = dict((h, h) for h in ra.fieldnames)
    wb.fieldnames = ra.fieldnames
    wb.writerow(dh)

  wb.writerow(d)

b.close()
a.close()

بافتراض أن لديك رؤوس في a.csv (لا تستطيع استخدام DictReader عليه) وتريد فقط نفس الرؤوس في b.csv .


Answer #4
from csv import DictReader, DictWriter

with open("input.csv", 'r') as input_file:
    reader = DictReader(f=input_file)
    with open("output.csv", 'w') as output_file:
        writer = DictWriter(f=output_file, fieldnames=reader.fieldnames)
        for row in reader:
            writer.writerow(row)




csv