Piszesz słownik do pliku tekstowego?

86

Mam słownik i próbuję zapisać go do pliku.

exDict = {1:1, 2:2, 3:3}
with open('file.txt', 'r') as file:
    file.write(exDict)

Mam wtedy błąd

file.write(exDict)
TypeError: must be str, not dict

Więc naprawiłem ten błąd, ale pojawił się inny błąd

exDict = {111:111, 222:222}
with open('file.txt', 'r') as file:
    file.write(str(exDict))

Błąd:

file.write(str(exDict))
io.UnsupportedOperation: not writable

Nie mam pojęcia, co robić, ponieważ nadal jestem początkującym użytkownikiem Pythona. Jeśli ktoś wie, jak rozwiązać problem, prosimy o udzielenie odpowiedzi.

UWAGA: używam Pythona 3, a nie Pythona 2

Nic
źródło

Odpowiedzi:

143

Przede wszystkim otwierasz plik w trybie do odczytu i próbujesz do niego pisać. Konsultacja - tryby IO python

Po drugie, do pliku można zapisywać tylko ciąg znaków. Jeśli chcesz napisać obiekt słownika, musisz przekształcić go w łańcuch lub serializować.

import json

# as requested in comment
exDict = {'exDict': exDict}

with open('file.txt', 'w') as file:
     file.write(json.dumps(exDict)) # use `json.loads` to do the reverse

W przypadku serializacji

import cPickle as pickle

with open('file.txt', 'w') as file:
     file.write(pickle.dumps(exDict)) # use `pickle.loads` to do the reverse

W przypadku pythona 3.x import pakietu pickle byłby inny

import _pickle as pickle
hspandher
źródło
1
To się udało! Chociaż zapisuje tylko zawartość słownika. Czy możesz go napisać: exDict = {111: 111, 222: 222}
Nic
Myślałem o tym, ale pomyślałem, że jest lepszy sposób. Ale działa, więc dziękuję!
Nic
Jeśli nie jesteś zbyt przywiązany do =znaku, moja edycja może załatwić sprawę.
hspandher
Tak jak wcześniej: file.write ('exDict =' + json.dumps (exDict)) działało dobrze, ponieważ używam go teraz.
Nic
1
@JanKukacka JSON to standardowy format danych. To str(exDict), co dałoby, nie zawsze będzie prawidłowym kodem JSON. Jednym z powodów z tyłu głowy jest to, że pojedyncze cudzysłowy nie są prawidłowe w pliku JSON, podczas gdy mogą występować, gdy używamy strmetody.
hspandher
49

Robię to tak w Pythonie 3:

with open('myfile.txt', 'w') as f:
    print(mydictionary, file=f)
NKSHELL
źródło
1
Podoba mi się ten, ponieważ nie jest potrzebny import. Odpowiedź dalej powyżej data.write (str (słownik)) nie będzie działać z poprawnym słownikiem, ponieważ po prostu zapisze <class 'dict'> w twoim pliku
Si Pon
Ciekawi mnie też, dlaczego nie po prostu wydrukować (mydictionary, file = open ('myfile.txt', 'w'))
MadmanLee
@MadmanLee Myślę, że oba są w porządku i jest to kwestia tego, jak preferujemy wygląd naszego kodu.
NKSHELL
1
with open ('myfile.txt', 'r') as f: content = f.read (); dic = eval (zawartość);
NKSHELL
Powodem, dla którego json jest lepsze niż zwykłe zapisywanie str(mydict)do pliku, jest właśnie to, że nie potrzebujesz evalzawartości, aby odzyskać dictobiekt. evalto rosk bezpieczeństwa i nie powinien być używany, jeśli dostępne są lepsze opcje.
snakecharmerb
22
fout = "/your/outfile/here.txt"
fo = open(fout, "w")

for k, v in yourDictionary.items():
    fo.write(str(k) + ' >>> '+ str(v) + '\n\n')

fo.close()
Sange Negru
źródło
12
Odpowiedzi zawierające tylko kod są odradzane, ponieważ nie wyjaśniają, jak rozwiązują problem. Zaktualizuj swoją odpowiedź, aby wyjaśnić, w jaki sposób poprawia to w stosunku do innych zaakceptowanych i pozytywnie ocenionych odpowiedzi, które już ma to pytanie. Przejrzyj Jak napisać dobrą odpowiedź .
FluffyKitten,
Powinieneś także używać withinstrukcji podczas czytania i zapisywania do plików: stackoverflow.com/questions/3012488/ ...
Falko
13

Problem z pierwszym blokiem kodu polegał na tym, że otwierałeś plik jako „r”, mimo że chciałeś do niego pisać używając 'w'

with open('/Users/your/path/foo','w') as data:
    data.write(str(dictionary))
clyde_the_frog
źródło
to jest prawidłowa odpowiedź, ponieważ kod w pytaniu zawiera błąd.
Ricardo Rivaldo
Kiedy próbuję użyć trasy json, otrzymuję błąd, ponieważ mam pewne wartości „NaN” w obiektach zmiennoprzecinkowych. Nie ma rozwiązania bez uszkodzenia samych danych, jeśli chcesz pisać w formacie JSON. Dlatego ta odpowiedź jest preferowana, ponieważ może zapisać plik tekstowy, aby dokładnie odzwierciedlić dyktando.
pauljohn32
7

Jeśli potrzebujesz słownika, który możesz zaimportować z pliku według nazwy, a także dodaje wpisy, które są ładnie posortowane i zawierają ciągi znaków, które chcesz zachować, możesz spróbować tego:

data = {'A': 'a', 'B': 'b', }

with open('file.py','w') as file:
    file.write("dictionary_name = { \n")
    for k in sorted (data.keys()):
        file.write("'%s':'%s', \n" % (k, data[k]))
    file.write("}")

Następnie do importu:

from file import dictionary_name
MarMat
źródło
Działa to tylko dla łańcuchów, a nie dla innych typów w słowniku.
Paul Kenjora
4

Dla miłośników rozumienia ze zrozumieniem listy wszystkie key : valuepary zostaną zapisane w nowych wierszachdog.txt

my_dict = {'foo': [1,2], 'bar':[3,4]}

# create list of strings
list_of_strings = [ f'{key} : {my_dict[key]}' for key in my_dict ]

# write string one by one adding newline
with open('dog.txt', 'w') as my_file:
    [ my_file.write(f'{st}\n') for st in list_of_strings ]
DavideL
źródło
1

Wiem, że to stare pytanie, ale pomyślałem również o udostępnieniu rozwiązania, które nie obejmuje json. Osobiście nie lubię json, ponieważ nie pozwala na łatwe dołączanie danych. Jeśli punktem początkowym jest słownik, możesz najpierw przekonwertować go na ramkę danych, a następnie dołączyć go do pliku txt:

import pandas as pd
one_line_dict = exDict = {1:1, 2:2, 3:3}
df = pd.DataFrame.from_dict([one_line_dict])
df.to_csv('file.txt', header=False, index=True, mode='a')

Mam nadzieję, że to pomoże.

Angelo
źródło
1
po co używać zewnętrznej biblioteki do prostego zadania? Python Simple to lepsza zasada.
Ricardo Rivaldo
Niezbyt przydatne, ponieważ większość używanych przeze mnie słowników nie jest na tyle prosta, aby stać się użytecznymi obiektami DataFrame.
pauljohn32
1
exDict = {1:1, 2:2, 3:3}
with open('file.txt', 'w+') as file:
    file.write(str(exDict))
Ianzo
źródło
-2
import json

with open('tokenler.json', 'w') as file:
     file.write(json.dumps(mydict, ensure_ascii=False))
malibayram91
źródło
Możesz poprawić ten błąd, dodając wyjaśnienie, dlaczego to działa.
Greg the Incredulous