-1

I have a txt file that I want to convert in a dictionary. Every file of the txt is made up of four str separated by semicolon. Each str will be the value of the dictionary. I tried the code below, but I am stack how to continue.

text = "1;Mike;Brown;73/04/01; 2;Anna;Smith;71/02/01"
file = open ("people.txt", "w")
file.write(tex)
file.close() file = open> ("people.txt", "r")
text = file.read()
file.close()
list => text.split(";") keys = ['id', 'name', 'family name', 'Birth']

Expected:

id: 1
name: Mikael
family name: Brown
Birth: 73/04/01

id: 2
name: Anna
family name: Smith
Birth: 71/02/01

Thanks

Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91

5 Answers5

1

I'll go ahead and assume that you're okay with having each dictionary key be associated with the list of matches across all lines in your text file.

What I mean by that is that if personal_data your dictionary then you would have the following:

>>> personal_data["id"]
[1, 2] 

Here is code that builds the dict as necessary. I'm going to omit any code to handle improper formatting and assume every entry has the same keys in the same order, and that groups of values in your text file contain no spaces .

personal_data = {'id':[],'name': [], 'family name': [], 'Birth': []}
keys = list(personal_data.keys())

# this is preferential to using open() and close()
with open('people.txt','r') as file_iterator: 
  for line in file_iterator:
     for entry in line.split(): # assuming fields don't contain spaces
       for i, value in enumerate(entry.split(';')):
         if i < len(keys): # to prevent IndexErrors in the case of a semicolon at the end
           personal_data[keys[i]].append(value)
    

On my Python 3.9.2 install I get:

{'id': ['1', '2'],
 'name': ['Mike', 'Anna'],
 'family name': ['Brown', 'Smith'],
 'Birth': ['73/04/01', '71/02/01']}

If possible, I think you'd really benefit from modifying the layout of your text file to be more amenable. Namely, splitting entries for each person across lines. Instead of:

1;Mike;Brown;73/04/01; 2;Anna;Smith;71/02/01

you could have:

1;Mike;Brown;73/04/01
2;Anna;Smith;71/02/01

The main motivation for this is it will make it easier to handle values which may have spaces in them like "Maria José", "Sarah Lynn", "dela Cruz". In general, building software which can deal with names can be quite tricky.


As you probably noticed, data like this is quite amenable to tabular formats, like what you'd see in a spreadsheet. Perhaps you'd benefit from putting it in a pandas.DataFrame object? The link takes you to the tutorial in their documentation, which should help you decide if it would be of use.

dwrodri
  • 122
  • 1
  • 4
1

This may be a bit off the mark, but

  • if "; " delimits records, and
  • ";" then delimits fields

Then this will produce the output you seem to want, aside from the file i/o:

if __name__ == '__main__':
    KEYS = ['id', 'name', 'family name', 'Birth']
    DATA = '1;Mike;Brown;73/04/01; 2;Anna;Smith;71/02/01;'

    things = []
    # assuming "; " separates logical records...
    for line in DATA.split('; '):
        result = {}
        values =  line.split(';')
        for key, value in zip(KEYS, values):
            # of course, one could just as easily print/persist here directly, but
            #  perhaps resulting dict is useful in other places 
            result[key] = value
        things.append(result)

    for record in things:
        for key, value in record.items():
            print(f'{key}: {value}')

# running this as a script produces:
id: 1
name: Mike
family name: Brown
Birth: 73/04/01
id: 2
name: Anna
family name: Smith
Birth: 71/02/01

Or if you prefer a rather nasty list/dict comprehension approach done interactively:

>>> data = '1;Mike;Brown;73/04/01; 2;Anna;Smith;71/02/01;'
>>> keys = ['id', 'name', 'family name', 'Birth']
>> [{k: v for k, v in zip(keys, line.split(';'))} for line in data.split('; ')]
[{'id': '1', 'name': 'Mike', 'family name': 'Brown', 'Birth': '73/04/01'}, {'id': '2', 'name': 'Anna', 'family name': 'Smith', 'Birth': '71/02/01'}]
zeromaster
  • 11
  • 1
1

use csv and dictreader

  • t.txt
id;name;family name;Birth
1;Mike;Brown;73/04/01
2;Anna;Smith;71/02/01

  • script
import csv

with open('t.txt','r') as file:
    f=csv.DictReader(file,delimiter=';')
    for i in f:
        print(i)

  • output
    {'id': '1', ' name': 'Mike', ' family name': 'Brown', ' Birth': '73/04/01'}
    {'id': '2', ' name': 'Anna', ' family name': 'Smith', ' Birth': '71/02/01'}
DevScheffer
  • 491
  • 4
  • 15
0
textlst = text.split(';')
dictlst = []
for i in range(0, len(textlst), 4):
    dictlst.append({"id" : int(textlst[i]), "name": textlst[i+1],  "family name": textlst[i+2], "Birth": textlst[i+3])

Get the whole file as a string, then split it by semi-colons, since we know we are going by four, we create a for loop that jumps by 4 every time. Then I had a dictlst array that I append to every 4 steps

0

Do you want this -

text = "1;Mike;Brown;73/04/01; 2;Anna;Smith;71/02/01"
result = [dict(zip(['Id','Name','family name', 'Birth'],item)) for item in list(map(lambda x : x.strip(';').split(';'),text.split()))]
Nk03
  • 14,699
  • 2
  • 8
  • 22