Her 'anahtar: değer' için bir satır olacak şekilde csv dosyasına bir sözlük yazmak


92

Bir sözlüğüm var:

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

Verileri bir dict.csv dosyasına şu tarzda yazmak istiyorum:

key1: value_a
key2: value_b
key3: value_c

Yazdım:

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

Ama şimdi tüm anahtarlar bir satırda ve tüm değerler bir sonraki satırda var ..

Böyle bir dosya yazmayı başardığımda, onu yeni bir sözlüğe de okumak istiyorum.

Sadece kodumu açıklamak için, sözlük textctrls ve checkbox'lardan (wxpython kullanarak) değerleri ve boolleri içerir. "Ayarları kaydet" ve "Ayarları yükle" düğmelerini eklemek istiyorum. Kayıt ayarları sözlüğü dosyaya belirtilen şekilde yazmalıdır (kullanıcının csv dosyasını doğrudan düzenlemesini kolaylaştırmak için), yükleme ayarları dosyadan okunmalı ve textctrls ve onay kutularını güncellemelidir.


1
çıktı olarak ne istediğinize dair daha iyi bir örnek verebilir misiniz? Yukarıda sahip olduğunuz "stil" CSV değil. Aradığınız key1, value_a [linebreak] key2, value_b [linebreak] key3, value_c?
tkone

Diğer bir yaklaşım, repr()dikteyi yazmak ve ardından dizeyi okuduğunuzda değerlendirmek için kullanmaktır. Bu eski SO gönderisine , str()vs. repr()ve dokümanlar tartışmaları için bakın .
Peter Rowell

Aşağıdaki cevabımın dışında, basit bir CSV dosyasından biraz daha karmaşık bir şey tercih ediyorsanız, ConfigParsermodülü kontrol etmek isteyebilirsiniz
Ricardo Cárdenes

3
Tanımladığınız şey, csv modülü tarafından yazılan tipik CSV biçimidir. Aynı anahtarlarla birden fazla
dikt yazarsanız

Yanıtlar:


186

DictWriterBeklediğiniz gibi çalışmaz.

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

Tekrar okumak için:

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

Bu oldukça kompakttır, ancak okurken herhangi bir tür dönüşümü yapmanız gerekmediğini varsayar


2
Mmh ... Tam olarak CSV'ye benzemeyen belirli bir format istediğinizi fark ettim. CSV modülünü kullandığınız için CSV stilini (yani anahtar-değer çifti başına bir satır) istediğiniz
varsayılmıştır

3
Veya ... CSV yaklaşımı tam olarak istediğiniz delimiter=':'
şeyse

2
Not, dosyayı yazma ve okuma arasında kapatmalısınız. Bu soruda / yanıtta ne olduğunu görün: stackoverflow.com/a/38467563/235698
Mark Tolonen

1
@MarkTolonen kullanmak kesinlikle withdaha iyi olur. Örnekleri yansıtacak şekilde değiştireceğim ...
Ricardo Cárdenes

1
@DareYang gecikme için özür dilerim. Aslında o zamanlar neden yazdığımı bilmiyorum. Buna gerek yok. Yazarken, bunun etkisi, satırsonu karakterlerini çevrilmemiş olarak bırakmaktır (yani \n, yazarsanız \n, dosyaya girersiniz). Yalnız bırakılırsa, "evrensel mod" devreye girer ve yeni satırlar mevcut işletim sistemi için varsayılana çevrilir. Burada gerçekten kullanışlı olmadığı göz önüne alındığında (tahmin edilebilir yeni satırlara sahip olmak istemeniz dışında), onu kaldıracağım.
Ricardo Cárdenes

27

Sadece bir seçenek vermek gerekirse, csv dosyasına bir sözlük yazmak da pandas paketi ile yapılabilir. Verilen örnekle bunun gibi bir şey olabilir:

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))

Dikkate alınması gereken en önemli şey, from_dict yönteminin içindeki 'orient' parametresini 'index' olarak ayarlamaktır . Bu, her sözlük anahtarını yeni bir satıra yazmak isteyip istemediğinizi seçmenizi sağlar.

Ek olarak, to_csv yönteminin içinde başlık parametresi, sadece rahatsız edici satırlar olmadan sadece sözlük öğelerine sahip olmak için False olarak ayarlanır. To_csv yöntemi içinde her zaman sütun ve dizin adlarını ayarlayabilirsiniz.

Çıktınız şöyle görünecektir:

key1,a
key2,b
key3,c

Bunun yerine, anahtarların sütun adları olmasını istiyorsanız, dokümantasyon bağlantılarını kontrol edebileceğiniz için, yalnızca "sütunlar" olan varsayılan "yön" parametresini kullanın.


2
Mükemmel bir cazibe gibi çalıştı :). Değerim bir listeydi ve csv'mi birden çok hücrede bulunan tüm liste değerleriyle oluşturdu ve ilk sütundaki anahtara eşlendi.
vinsinraw

14

En kolay yol, csv modülünü yok saymak ve onu kendiniz biçimlendirmektir.

with open('my_file.csv', 'w') as f:
    [f.write('{0},{1}\n'.format(key, value)) for key, value in my_dict.items()]

8
Eğer keyvirgül alırsanız, kötü zaman geçireceksiniz.
Ali Ashraf

5
Sadece kullanmayı daha kolay buluyorum csv.writer(...).writerows(my_dict.items()). csvModül daha fazlasına göre sadece virgül ve yeni satır eklemek gelmez.
Martijn Pieters

6
outfile = open( 'dict.txt', 'w' )
for key, value in sorted( mydict.items() ):
    outfile.write( str(key) + '\t' + str(value) + '\n' )

1
Lütfen cevabınızla ilgili bazı bilgiler veya yorumlar da sağlayın.
NDM

2

Sadece yapabilir misin:

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

Böylece sahip olabilirsin

key_1: değer_1, anahtar_2: değer_2


3
Daha ','.join("%s:%s" % (k,v) for k,v in mydict.items())iyisi - genellikle bir diktenin öğelerini yinelemekten daha iyidir, bu da size anahtarları ve değerleri birlikte verir, bir diktenin anahtarlarından ve 'n' değer aramalarından çok. ','.join(...)sondaki fazladan virgül eklemeden değerler arasına yalnızca virgül koymaya özen gösterir.
PaulMcG

bu python kodu için sondaki noktalı virgül gerekmeyeceğini unutmayın
beep_check

1

Ben şahsen csv modülünü her zaman sinir bozucu buldum. Başka birinin size bunu nasıl düzgün bir şekilde yapacağınızı göstermesini bekliyorum, ancak benim hızlı ve kirli çözümüm:

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

Bununla birlikte, tekrar okumak istiyorsanız, özellikle de hepsi tek satırdaysa, rahatsız edici bir ayrıştırma yapmanız gerekir. Önerilen dosya biçiminizi kullanan bir örnek aşağıda verilmiştir.

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

Ricardo'nun cevabıyla giderdim. Ya da en azından ayrı satırlar kullanın.
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() 

görüntü açıklamasını buraya girin


Son satırdaki dosyayı açıkça kapatmanız gerektiğini düşünmüyorum. İçerik yöneticisi bunu sizin için yapar.
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

Küçük bir açıklama eklerseniz daha iyi olur
Roaim

-2

: Üzerinde "s" eklemeyi denediniz mi w.writerow(mydict)böyle: w.writerows(mydict)? Bu sorun başıma geldi ama listelerde çoğul yerine tekil kullanıyordum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.