1
votes

Python3 - dict imbriqué en JSON

J'essaie de convertir plusieurs fichiers .txt en données "de type table" (avec des colonnes et des lignes). Chaque fichier .txt doit être considéré comme une nouvelle colonne.

Tenez compte du contenu ci-dessous du fichier .txt :

File1. txt

def saveJsonFile(text_file, data):

    basename = os.path.splitext(os.path.basename(text_file))
    dir_name = os.path.dirname(text_file) + "/"
    text_file = dir_name + basename[0] + "1.txt"

    out_file = dir_name + 'table_data.txt'

    with open(out_file, 'a+') as f:
        f.write(json.dumps(data))

File2.txt

 data = defaultdict(list)

 for path in images.values():
     column = column + 1

     data[str(column)] = txtFileToJson(path, column)

 saveJsonFile(path, data)

J'ai créé un simple méthode, qui accepte le fichier et et un entier (le numéro de fichier d'une autre méthode):

[{"1": "Hi there\n"}, {"2": "How are you doing?\n"}, {"3": "\n"}, {"4": "What is your name?"}]
[{"1": "Hi\n"}, {"2": "Great!\n"}, {"3": "\n"}, {"4": "Oliver, what's yours?"}]

La méthode ci-dessus s'exécutera deux fois (une fois pour chaque fichier, et ajoutera le data).

Voici le fichier output.txt après avoir exécuté mon script:

myDict = {str(column): []}
i = int(1)
with open(text_file) as f:
    for line in f:
        # data[column].append(column)
        match = re.split(r'[\n\r]+', line)
        if match:
            myDict[str(column)].append({str(i): line})
            i = i + 1

with open(out_file, 'a+') as f:
    f.write(json.dumps(myDict[str(column)]))

Comme vous pouvez le voir , Je ne peux l'obtenir que pour créer un nouveau pour chaque fichier que j'ai, puis ajouter la ligne entière.

[{
   "1": [{
       "1": "Hi there",
       "2": "How are you doing?",
       "3": "\n"
       "4": "What is your name?"
   },
   "2": [{
       "1": "Hi"
       "2": "Great!",
       "3": "\n",
       "4": "Oliver, what's yours?"
   },
}]

Mise à jour:

OK, donc J'ai joué un peu et je me suis rapproché un peu:

{"1": "What is your name?"}{"2": "Oliver, what's yours?"}

Cela me donne la sortie ci-dessous:

def txtFileToJson(text_file, column):

    data = defaultdict(list)

    i = int(1)
    with open(text_file) as f:

        data[column].append(column)

        for line in f:
            i = i + 1
            for line in re.split(r'[\n\r]+', line):
                data[column] = line

    with open("output.txt", 'a+') as f:
        f.write(json.dumps(data))

Mais comme vous peut voir, maintenant j'ai plusieurs éléments racine JSON.

Solution

Grâce à jonyfries, j'ai fait ceci:

Hi
Great!

Oliver, what's yours?

Et puis ajouté une nouvelle méthode pour enregistrer la liste combinée finale:

Hi there
How are you doing?

What is your name?


3 commentaires

Pouvez-vous peut-être montrer le résultat souhaité?


C'est déjà dans ma question. Juste avant la mise à jour.


Il doit y avoir exactement un json.dump . Il n'est pas possible de créer un JSON valide en concaténant des JSON plus petits.


3 Réponses :


1
votes

Vous créez un nouveau dictionnaire dans la fonction elle-même. Ainsi, chaque fois que vous y passez un fichier texte, vous créez un nouveau dictionnaire.

La solution la plus simple semble être de renvoyer le dictionnaire créé et de l'ajouter à un dictionnaire existant.

def txtFileToJson(text_file, column):
    myDict = {str(column): []}
    i = int(1)
    with open(text_file) as f:
        for line in f:
            # data[column].append(column)
            match = re.split(r'[\n\r]+', line)
            if match:
                myDict[str(column)].append({str(i): line})
                i = i + 1

    with open(out_file, 'a+') as f:
        f.write(json.dumps(myDict[str(column)]))

    return myDict

data = defaultdict(list)

data["1"] = txtFileToJson(text_file, column)
data["2"] = txtFileToJson(other_text_file, other_column)


1 commentaires

Ah, bien sûr! Ça marche. Je mettrai à jour ma question pour afficher mon code mis à jour.



0
votes
def read(text_file):
    data, i = {}, 0
    with open(text_file) as f:
        for line in f:
            i = i + 1
            data['row_%d'%i] = line.rstrip('\n')
    return data

res = {}
for i, fname in enumerate([r'File1.txt', r'File2.txt']):
    res[i] = read(fname)
with open(out_file, 'w') as f:
    json.dump(res, f)

0 commentaires

0
votes

Premièrement, si je comprends que vous essayez d'obtenir en sortie un dictionnaire de dictionnaires, laissez-moi observer que ce que je comprends être la sortie souhaitée semble englober le tout dans une liste, De plus, vous avez ouvert déséquilibré et des crochets de liste fermée dans les dictionnaires, que je vais ignorer, comme je le ferai pour la liste ci-jointe.

Je pense que vous avez besoin de quelque chose comme:

data[str(n)] = [d]

Si vous avez vraiment besoin du les dictionnaires imbriqués à inclure dans une liste, puis remplacer

data[str(n)] = d

par:

#!python3

import json
import re

def processTxtFile(text_file, n, data):
    d = {}
    with open(text_file) as f:
        i = 0
        for line in f:
            for line in re.split(r'[\n\r]+', line):
                i = i + 1
                d[str(i)] = line
    data[str(n)] = d


data = dict()
processTxtFile('File1.txt', 1, data)
processTxtFile('File2.txt', 2, data)
with open("output.txt", 'wt') as f:
    f.write(json.dumps(data))


0 commentaires