Python sözlüklerini saklama


198

.Csv dosyalarını kullanarak Python'a veri girip çıkarmaya alışkınım, ancak bununla ilgili bariz zorluklar var. Bir sözlük (veya sözlük setleri) bir json veya pck dosyasında saklamanın basit yolları hakkında herhangi bir tavsiye? Örneğin:

data = {}
data ['key1'] = "keyinfo"
data ['key2'] = "keyinfo2"

Bunu nasıl kaydedeceğimizi ve sonra nasıl geri yükleyeceğinizi bilmek istiyorum.


8
Json veya turşu standart modülleri için belgeleri okudunuz mu?
Greg Hewgill

Yanıtlar:


444

Turşu tasarrufu:

try:
    import cPickle as pickle
except ImportError:  # python 3.x
    import pickle

with open('data.p', 'wb') as fp:
    pickle.dump(data, fp, protocol=pickle.HIGHEST_PROTOCOL)

Argümanla ilgili ek bilgi için turşu modülü belgelerine bakın protocol.

Turşu yükü:

with open('data.p', 'rb') as fp:
    data = pickle.load(fp)

JSON kaydetme:

import json

with open('data.json', 'w') as fp:
    json.dump(data, fp)

Güzel bir sonuç almak için sort_keysveya gibi ekstra argümanlar indentsağlayın. Sort_keys bağımsız değişkeni , anahtarları alfabetik olarak sıralar ve girinti , veri yapınızı indent=Nboşluklarla girintili hale getirir .

json.dump(data, fp, sort_keys=True, indent=4)

JSON yükü:

with open('data.json', 'r') as fp:
    data = json.load(fp)

4
JSON sözlükleri yerel olarak yapar (açıkçası bir python sözlüğünün bellekte olduğu gibi tam olarak davranmalarına rağmen, kalıcılık amaçları için aynıdır). Aslında, json'daki temel birim, {<string>: <value>} olarak tanımlanan "Object" dir. Tanıdık görünmek? Standart kitaplıktaki json modülü, her Python yerel türünü destekler ve kullanıcı tanımlı sınıfları desteklemek için minimum json bilgisi ile kolayca genişletilebilir. JSON ana sayfası , dili 3 yazdırılmış sayfanın üzerinde tamamen tanımlar, bu nedenle hızlı bir şekilde emilmesi / sindirilmesi kolaydır.
Jonathanb

1
Üçüncü argümanı da bilmeye değer pickle.dump. Dosyanın insan tarafından okunabilir olması gerekmiyorsa, işleri çok hızlandırabilir.
Steve Jessop

11
Eğer döküm çağrısına sort_keys ekler ve argüman girintilerseniz çok daha güzel bir sonuç elde edersiniz. örneğin: json.dump(data, fp, sort_keys=True, indent=4). Daha fazla bilgi burada
juliusmh

1
Muhtemelen kullanmalısınızpickle.dump(data, fp, protocol=pickle.HIGHEST_PROTOCOL)
Martin Thoma

1
Python 3 için, kullanınimport pickle
danger89

35

Doğrudan bir dosyaya yazılacak en az örnek:

import json
json.dump(data, open(filename, 'wb'))
data = json.load(open(filename))

veya güvenle açma / kapama:

import json
with open(filename, 'wb') as outfile:
    json.dump(data, outfile)
with open(filename) as infile:
    data = json.load(infile)

Dosya yerine dizeye kaydetmek istiyorsanız:

import json
json_str = json.dumps(data)
data = json.loads(json_str)


5

Bir dosyaya yazmak için:

import json
myfile.write(json.dumps(mydict))

Bir dosyadan okumak için:

import json
mydict = json.loads(myfile.read())

myfile , dikteyi sakladığınız dosyanın dosya nesnesidir.


json dosyaları bağımsız değişken olarak almak ve doğrudan onlara yazmak olan eşya vardır?

json.dump(myfile)vejson.load(myfile)
Niklas R

5

Serileştirmeden sonraysanız ancak diğer programlardaki verilere ihtiyacınız yoksa shelvemodülü şiddetle tavsiye ederim . Bunu kalıcı bir sözlük olarak düşünün.

myData = shelve.open('/path/to/file')

# check for values.
keyVar in myData

# set values
myData[anotherKey] = someValue

# save the data for future use.
myData.close()

2
Bütün bir dikdörtgeni saklamak veya bütün bir dikteyi yüklemek istiyorsanız json, daha uygundur. shelvebir kerede yalnızca bir anahtara erişmek için daha iyidir.
agf

3

pickleVeya 'ye alternatif jsonistiyorsanız kullanabilirsiniz klepto.

>>> init = {'y': 2, 'x': 1, 'z': 3}
>>> import klepto
>>> cache = klepto.archives.file_archive('memo', init, serialized=False)
>>> cache        
{'y': 2, 'x': 1, 'z': 3}
>>>
>>> # dump dictionary to the file 'memo.py'
>>> cache.dump() 
>>> 
>>> # import from 'memo.py'
>>> from memo import memo
>>> print memo
{'y': 2, 'x': 1, 'z': 3}

İle klepto, eğer kullansaydınız serialized=True, sözlük memo.pklaçık metin yerine turşu sözlük olarak yazılacaktı .

Alabilirsiniz klepto : https://github.com/uqfoundation/klepto

dill turşu için muhtemelen daha iyi bir seçimdir pickledillpython'da neredeyse her şeyi serileştirebileceği gibi kendisi . kleptoayrıca kullanabilirsiniz dill.

Buraya ulaşabilirsiniz dill: https://github.com/uqfoundation/dill

İlk birkaç satırdaki ek mumbo-jumbo, kleptosözlükleri bir dosyaya, bir dizin içeriğine veya bir SQL veritabanına depolayacak şekilde yapılandırılabilmesidir. API, arka uç arşivi olarak seçtiğiniz her şey için aynıdır. Kullanabileceğiniz loadve dumparşivle etkileşime girebileceğiniz "arşivlenebilir" bir sözlük sunar .


3

Bu eski bir konudur, ancak tamlık için, sırasıyla Python 2 ve 3'teki standart kütüphanenin bir parçası olan ConfigParser ve configparser'ı eklemeliyiz. Bu modül bir config / ini dosyasını okur ve yazar ve (en azından Python 3'te) sözlük gibi birçok şekilde davranır. Ayrıca, birden çok sözlükleri config / ini dosyanızın ayrı bölümlerine kaydedip hatırlatabilirsiniz. Tatlı!

Python 2.7.x örneği.

import ConfigParser

config = ConfigParser.ConfigParser()

dict1 = {'key1':'keyinfo', 'key2':'keyinfo2'}
dict2 = {'k1':'hot', 'k2':'cross', 'k3':'buns'}
dict3 = {'x':1, 'y':2, 'z':3}

# make each dictionary a separate section in config
config.add_section('dict1')
for key in dict1.keys():
    config.set('dict1', key, dict1[key])

config.add_section('dict2')
for key in dict2.keys():
    config.set('dict2', key, dict2[key])

config.add_section('dict3')
for key in dict3.keys():
    config.set('dict3', key, dict3[key])

# save config to file
f = open('config.ini', 'w')
config.write(f)
f.close()

# read config from file
config2 = ConfigParser.ConfigParser()
config2.read('config.ini')

dictA = {}
for item in config2.items('dict1'):
    dictA[item[0]] = item[1]

dictB = {}
for item in config2.items('dict2'):
    dictB[item[0]] = item[1]

dictC = {}
for item in config2.items('dict3'):
    dictC[item[0]] = item[1]

print(dictA)
print(dictB)
print(dictC)

Python 3.X örneği.

import configparser

config = configparser.ConfigParser()

dict1 = {'key1':'keyinfo', 'key2':'keyinfo2'}
dict2 = {'k1':'hot', 'k2':'cross', 'k3':'buns'}
dict3 = {'x':1, 'y':2, 'z':3}

# make each dictionary a separate section in config
config['dict1'] = dict1
config['dict2'] = dict2
config['dict3'] = dict3

# save config to file
f = open('config.ini', 'w')
config.write(f)
f.close()

# read config from file
config2 = configparser.ConfigParser()
config2.read('config.ini')

# ConfigParser objects are a lot like dictionaries, but if you really
# want a dictionary you can ask it to convert a section to a dictionary
dictA = dict(config2['dict1'] )
dictB = dict(config2['dict2'] )
dictC = dict(config2['dict3'])

print(dictA)
print(dictB)
print(dictC)

konsol çıkışı

{'key2': 'keyinfo2', 'key1': 'keyinfo'}
{'k1': 'hot', 'k2': 'cross', 'k3': 'buns'}
{'z': '3', 'y': '2', 'x': '1'}

config.ini içeriği

[dict1]
key2 = keyinfo2
key1 = keyinfo

[dict2]
k1 = hot
k2 = cross
k3 = buns

[dict3]
z = 3
y = 2
x = 1

1

Bir json dosyasına kaydederseniz, bunu yapmanın en iyi ve en kolay yolu:

import json
with open("file.json", "wb") as f:
    f.write(json.dumps(dict).encode("utf-8"))

bu neden json.dump( )diğer cevapta belirtilenden daha kolay ?
baxx

0

benim durumum bir dosyaya birden fazla json nesnesi kaydetmek oldu ve marty cevabı bana biraz yardımcı oldu. Ancak benim kullanım durumuma hizmet etmek için, yanıt her yeni giriş kaydedildiğinde eski verilerin üzerine yazacağı için tamamlanmadı.

Bir dosyaya birden çok giriş kaydetmek için, eski içeriğin kontrol edilmesi gerekir (örneğin, yazmadan önce okuyun). Json verilerini tutan tipik bir dosyada bir listveya objectas kökü bulunur. Bu yüzden json dosyamın list of objectsher zaman veri eklediğini ve her veri eklediğimde, önce listeyi yüklediğim, yeni verilerimi eklediğim ve sadece yazılabilir bir dosya örneğine ( w) geri döktüğümü düşündüm :

def saveJson(url,sc): #this function writes the 2 values to file
    newdata = {'url':url,'sc':sc}
    json_path = "db/file.json"

    old_list= []
    with open(json_path) as myfile:  #read the contents first
        old_list = json.load(myfile)
    old_list.append(newdata)

    with open(json_path,"w") as myfile:  #overwrite the whole content
        json.dump(old_list,myfile,sort_keys=True,indent=4)

    return "sucess"

yeni json dosyası şöyle görünecektir:

[
    {
        "sc": "a11",
        "url": "www.google.com"
    },
    {
        "sc": "a12",
        "url": "www.google.com"
    },
    {
        "sc": "a13",
        "url": "www.google.com"
    }
]

NOT: adlı bir dosya olması esastır file.jsonile []çalışmalarına bu yaklaşım için başlangıç verisi olarak

Not: orijinal soru ile ilgili değildir, ancak bu yaklaşım ilk önce girişimizin zaten mevcut olup olmadığını (1 / çoklu tuşlara dayanarak) kontrol ederek ve daha sonra verileri ekleyip kaydederek daha da geliştirilebilir. Birisinin bu kontrole ihtiyacı varsa bana bildirin, cevaba ekleyeceğim

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.