Menulis kamus ke file csv dengan satu baris untuk setiap 'key: value'

92

Saya punya kamus:

mydict = {key1: value_a, key2: value_b, key3: value_c}

Saya ingin menulis data ke file dict.csv, dengan gaya ini:

key1: value_a
key2: value_b
key3: value_c

Saya menulis:

import csv
f = open('dict.csv','wb')
w = csv.DictWriter(f,mydict.keys())
w.writerow(mydict)
f.close()

Tapi sekarang saya memiliki semua kunci dalam satu baris dan semua nilai di baris berikutnya ..

Ketika saya berhasil menulis file seperti ini, saya juga ingin membacanya kembali ke kamus baru.

Hanya untuk menjelaskan kode saya, kamus berisi nilai dan nilai dari textctrls dan kotak centang (menggunakan wxpython). Saya ingin menambahkan tombol "Simpan setelan" dan "Muat setelan". Pengaturan penyimpanan harus menulis kamus ke file dengan cara yang disebutkan (untuk memudahkan pengguna mengedit file csv secara langsung), pengaturan beban harus membaca dari file dan memperbarui textctrls dan kotak centang.

pengguna1106770
sumber
1
dapatkah Anda memberikan contoh yang lebih baik tentang apa yang Anda inginkan sebagai keluaran? "gaya" yang Anda miliki di atas bukanlah CSV. yang Anda cari key1, value_a [linebreak] key2, value_b [linebreak] key3, value_c?
tkone
Pendekatan lain adalah menggunakan repr()untuk menulis dict dan kemudian mengevaluasi string tersebut ketika Anda membacanya. Lihatlah posting SO lama ini untuk diskusi tentang str()vs. repr(), dan dokumentasinya , juga.
Peter Rowell
Terlepas dari jawaban saya di bawah ini, jika Anda lebih memilih sesuatu yang sedikit lebih canggih daripada hanya file CSV biasa, Anda mungkin ingin memeriksa ConfigParsermodul
Ricardo Cárdenes
3
Yang Anda gambarkan adalah format CSV tipikal yang ditulis oleh modul csv. Jika Anda menulis beberapa dict dengan kunci yang sama, kunci hanya ditulis sekali, di baris pertama, dengan satu baris per dict untuk nilai yang sesuai, dalam urutan yang benar agar sejajar dengan kunci di baris 1.
PaulMcG

Jawaban:

187

Ini DictWritertidak bekerja seperti yang Anda harapkan.

with open('dict.csv', 'w') as csv_file:  
    writer = csv.writer(csv_file)
    for key, value in mydict.items():
       writer.writerow([key, value])

Untuk membacanya kembali:

with open('dict.csv') as csv_file:
    reader = csv.reader(csv_file)
    mydict = dict(reader)

yang cukup ringkas, tetapi mengasumsikan Anda tidak perlu melakukan konversi jenis apa pun saat membaca

Ricardo Cárdenes
sumber
2
Mmh ... Baru saja perhatikan bahwa Anda menginginkan format tertentu yang tidak persis seperti CSV. Diasumsikan bahwa Anda menginginkan gaya CSV (mis. Baris per pasangan nilai kunci) karena Anda menggunakan modul CSV ...
Ricardo Cárdenes
3
Atau ... jika pendekatan CSV persis seperti yang Anda inginkan, tetapi Anda lebih suka ":" sebagai pemisah, tambahkan saja delimiter=':'saat membuat penulis dan pembaca :)
Ricardo Cárdenes
2
Catatan, Anda harus menutup file antara menulis dan membaca. Lihat apa yang terjadi dalam pertanyaan / jawaban ini: stackoverflow.com/a/38467563/235698
Mark Tolonen
1
@MarkTolonen tentunya, menggunakan withakan lebih baik. Saya akan mengubah contoh untuk mencerminkannya ...
Ricardo Cárdenes
1
@DareYang maaf atas keterlambatannya. Sebenarnya, saya tidak yakin mengapa saya menulisnya saat itu. Itu tidak dibutuhkan. Saat menulis, efeknya adalah membiarkan karakter baris baru tidak diterjemahkan (mis. Jika Anda menulis \n, Anda akan masuk \nke file). Jika dibiarkan, "mode universal" akan dijalankan dan baris baru diterjemahkan ke default untuk sistem operasi saat ini. Mengingat bahwa ini tidak terlalu berguna di sini (kecuali jika Anda ingin memiliki baris baru yang dapat diprediksi), saya akan menghapusnya.
Ricardo Cárdenes
27

Hanya untuk memberi opsi, menulis kamus ke file csv juga bisa dilakukan dengan paket pandas. Dengan contoh yang diberikan, bisa jadi seperti ini:

mydict = {'key1': 'a', 'key2': 'b', 'key3': 'c'}

import pandas as pd

(pd.DataFrame.from_dict(data=mydict, orient='index')
   .to_csv('dict_file.csv', header=False))

Hal utama yang harus diperhatikan adalah menyetel parameter 'orient' ke 'index' di dalam metode from_dict . Ini memungkinkan Anda memilih apakah Anda ingin menulis setiap kunci kamus di baris baru.

Selain itu, di dalam metode to_csv , parameter header disetel ke False hanya untuk memiliki elemen kamus saja tanpa baris yang mengganggu. Anda selalu dapat mengatur nama kolom dan indeks di dalam metode to_csv.

Output Anda akan terlihat seperti ini:

key1,a
key2,b
key3,c

Jika sebaliknya Anda ingin kunci menjadi nama kolom, cukup gunakan parameter 'orient' default yaitu 'kolom', karena Anda dapat memeriksa di tautan dokumentasi.

Ivan Calderon
sumber
2
Sangat baik bekerja seperti pesona :). Nilai saya adalah sebuah daftar dan itu menghasilkan csv saya dengan semua nilai daftar dalam beberapa sel dan dipetakan ke kunci di kolom pertama.
vinsinraw
14

Cara termudah adalah dengan mengabaikan modul csv dan memformatnya sendiri.

with open('my_file.csv', 'w') as f:
    [f.write('{0},{1}\n'.format(key, value)) for key, value in my_dict.items()]
Phil Horowitz
sumber
8
Jika Anda keymendapat koma, Anda akan mengalami saat yang buruk.
Ali Ashraf
5
Saya merasa lebih mudah untuk hanya menggunakan csv.writer(...).writerows(my_dict.items()). The csvmodul tidak jauh lebih banyak dari hanya menambahkan koma dan baris baru.
Martijn Pieters
6
outfile = open( 'dict.txt', 'w' )
for key, value in sorted( mydict.items() ):
    outfile.write( str(key) + '\t' + str(value) + '\n' )
FCAlive
sumber
1
Berikan juga beberapa informasi atau komentar atas jawaban Anda.
NDM
2

Bisakah Anda melakukan:

for key in mydict.keys():
    f.write(str(key) + ":" + str(mydict[key]) + ",");

Sehingga Anda bisa memiliki

key_1: nilai_1, key_2: nilai_2

louis.luo
sumber
3
Lebih baik ','.join("%s:%s" % (k,v) for k,v in mydict.items())- Anda biasanya lebih baik melakukan iterasi terhadap item dict, yang memberi Anda kunci dan nilai bersama-sama, daripada di atas kunci dict dan melakukan pencarian nilai 'n'. ','.join(...)menangani hanya menempatkan koma di antara nilai, tanpa menambahkan tanda koma tambahan.
PaulMcG
perhatikan bahwa Anda tidak memerlukan titik koma di bagian akhir untuk kode python ini
beep_check
1

Saya pribadi selalu menemukan jenis modul csv yang mengganggu. Saya berharap orang lain akan menunjukkan kepada Anda bagaimana melakukan ini dengan licin dengannya, tetapi solusi cepat dan kotor saya adalah:

with open('dict.csv', 'w') as f:  # This creates the file object for the context 
                                  # below it and closes the file automatically
    l = []
    for k, v in mydict.iteritems(): # Iterate over items returning key, value tuples
        l.append('%s: %s' % (str(k), str(v))) # Build a nice list of strings
    f.write(', '.join(l))                     # Join that list of strings and write out

Namun, jika Anda ingin membacanya kembali, Anda perlu melakukan beberapa penguraian yang menjengkelkan, terutama jika semuanya dalam satu baris. Berikut adalah contoh penggunaan format file yang Anda usulkan.

with open('dict.csv', 'r') as f: # Again temporary file for reading
    d = {}
    l = f.read().split(',')      # Split using commas
    for i in l:
        values = i.split(': ')   # Split using ': '
        d[values[0]] = values[1] # Any type conversion will need to happen here
Griffith Rees
sumber
Saya akan setuju dengan jawaban Ricardo. Atau setidaknya gunakan baris terpisah.
Griffith Rees
0
import csv

dict = {"Key Header":"Value Header", "key1":"value1", "key2":"value2"}

with open("test.csv", "w") as f:
    writer = csv.writer(f)
    for i in dict:
      writer.writerow([i, dict[i]])
f.close() 

masukkan deskripsi gambar di sini

Apurva Thorat
sumber
Saya tidak berpikir Anda perlu menutup file secara eksplisit di baris terakhir. Manajer konteks melakukannya untuk Anda.
avaj_wen12
0
#code to insert and read dictionary element from csv file
import csv
n=input("Enter I to insert or S to read : ")
if n=="I":
    m=int(input("Enter the number of data you want to insert: "))
    mydict={}
    list=[]
    for i in range(m):
        keys=int(input("Enter id :"))
        list.append(keys)
        values=input("Enter Name :")
        mydict[keys]=values

    with open('File1.csv',"w") as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=list)
        writer.writeheader()
        writer.writerow(mydict)
        print("Data Inserted")
else:
    keys=input("Enter Id to Search :")
    Id=str(keys)
    with open('File1.csv',"r") as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            print(row[Id]) #print(row) to display all data
Ashish Nandan
sumber
Akan lebih baik jika Anda menambahkan sedikit penjelasan
Roaim
-2

Sudahkah Anda mencoba menambahkan "s" pada: w.writerow(mydict)seperti ini w.writerows(mydict):? Masalah ini terjadi pada saya tetapi dengan daftar, saya menggunakan tunggal, bukan jamak.

Hikhuj
sumber