Dump each element of list on new line (Python & JSON) - python

I have a list of dictionaries of the form:
mylist = [{'name': 'Johnny', 'surname': 'Cashew'}, {'name': 'Abraham', 'surname': 'Linfield'}]
and I am trying to dump that to a json this way:
with open('myfile.json', 'w') as f:
json.dump(mylist, f)
but then the entire list is on one line in the json file, making it hardly readable (my list is in reality very long). Is there a way to dump each element of my list on a new line? I have seen this post that suggests using indent in this way:
with open('myfile.json', 'w') as f:
json.dump(mylist, f, indent=2)
but then I get each element within the dictionaries on a new line, like that:
[
{
'name': 'Johnny',
'surname: 'Cashew'
},
{
'name': 'Abraham',
'surname: 'Linfield'
}
]
whereas what I am hoping to obtain is something like that:
[
{'name': 'Johnny', 'surname': 'Cashew'},
{'name': 'Abraham', 'surname': 'Linfield'}
]
Would someone have a hint? Many thanks!

This is a dirty way of doing it but it works for me
import json
my_list = [{'name': 'John', 'surname': 'Doe'}, {'name': 'Jane', 'surname': 'Doe'}]
with open('names.json','w') as f:
f.write('[\n')
for d in my_list:
#dumps() instead of dump() so that we can write it like a normal str
f.write(json.dumps(d))
if d == my_list[-1]:
f.write("\n")
break
f.write(",\n")
f.write(']')

Related

Convert structured content of text file to list with dictionaries

I'm reading a text file like this:
ATTACHMENT1=:1.xlsm
ATTACHMENT1RNG1=:Entity
ATTACHMENT1VRNG1=:TOT^^ENT1
ATTACHMENT1RNG2=:country
ATTACHMENT1VRNG2=:A
ATTACHMENT2=:2.xlsm
ATTACHMENT2RNG1=:Entity
ATTACHMENT2VRNG1=:TOT
ATTACHMENT2RNG2=:dept
ATTACHMENT2VRNG2=:F0008
and want to load it in list with dictionaries as in:
[
{'File': [1.xlsm'], 'Entity': ['TOT', 'ENT1'], 'country': ['A']},
{'File': [2.xlsm'], 'Entity': ['TOT'], 'dept': ['F0008']}
]
'File' is a fixed prefix for ATTACHMENT1 and ATTACHMENT2.
For the other lines I would like to have the value of RNGx as dictionary keys and the values of VRNGx as dictionary values.
I know I can split lines on '=:', I can also split a string based on a separator, but I cannot figure out how to create this data structure myself.
Any guidance would be very much appreciated.
Thanks in advance.
Assuming you can rely on the ordering, this is pretty easy to do with a state machine that just looks at the presence of the different suffixes:
with open("file.txt") as f:
data = []
key = ""
for line in f:
k, v = line.strip().split("=:")
if "RNG" not in k:
data.append({'File': [v]})
elif "VRNG" not in k:
key = v
else:
data[-1][key] = v.split("^^")
print(data)
[{'File': ['1.xlsm'], 'Entity': ['TOT', 'ENT1'], 'country': ['A']}, {'File': ['2.xlsm'], 'Entity': ['TOT'], 'dept': ['F0008']}]

change single quotes to double quotes in list of dictionaries

input=
list1=[{'Name':'Jack','email':'xyz#foo.com'},
{'Name':'Sam','email':'sam#xyz.com'},
{'Name':'Dan','email':'dan#xyz.com'}]
Required output =
list1=[{"Name":"Jac","email":"xyz#foo.com"},
{"Name":"Sam","email":"sam#xyz.com"},
{"Name":"Dan","email":"dan#xyz.com"}]
How to get this as output? I've tried
list2=[]
for items in response:
list2.append(json.dumps(items))
output I'm getting is
['{'Name':'Jack','email':'xyz#foo.com'}',
'{'Name':'Sam','email':'sam#xyz.com'}',
'{'Name':'Dan','email':'dan#xyz.com'}']
Please use json.dumps like this:
import json
list1=[{'Name':'Jack','email':'xyz#foo.com'},
{'Name':'Sam','email':'sam#xyz.com'},
{'Name':'Dan','email':'dan#xyz.com'}]
print(list1)
list2 = json.dumps(list1)
print(list2)
#[{'Name': 'Jack', 'email': 'xyz#foo.com'}, {'Name': 'Sam', 'email': 'sam#xyz.com'}, {'Name': 'Dan', 'email': 'dan#xyz.com'}]
#[{"Name": "Jack", "email": "xyz#foo.com"}, {"Name": "Sam", "email": "sam#xyz.com"}, {"Name": "Dan", "email": "dan#xyz.com"}]
Generally, you want to do json.dumps() on the whole data structure, not on individual pieces.
It's not clear from your question what form the input is; is it a data structure in a file, or in memory?
If it's in a file, the first step will be reading it, so it's in memory, and so each part has the right form.
Once that's done, you can do json.dumps() on the whole list.

Export Dictionary with Both Simple Values and Nested Dictionaries to CSV

I'm accessing a third-party API that returns a dictionary that contains both simple values and nested (embedded?) dictionaries. I need to convert this to a CSV file, but I need help extracting and exporting specific values from the nested dictionaries.
Here's a simplified example of what I'm getting back:
accounts = {
'Id': '0131232',
'AccountName': 'CompanyX',
'Active': False,
'LastModifiedBy': {'type': 'User', 'Id': '', 'Name': 'Joe Smith'}
},
{
'Id': '987654',
'AccountName': 'CompanyY',
'Active': True,
'LastModifiedBy': {'type': 'User', 'Id': '', 'Name': 'Mary Johnson'}
}
I'm trying to export this to a CSV file with the following code:
with open('output.csv', 'w') as f:
dwriter = csv.DictWriter(f, accounts[0].keys())
dwriter.writeheader()
dwriter.writerows(accounts)
f.close()
What I want in the CSV file is the following:
Id,AccountName,Active,LastModifiedBy
0131232,CompanyX,False,Joe Smith
987654,CompanyY,True,Mary Johnson
What I'm getting with my code above is the following:
Id,AccountName,Active,LastModifiedBy
0131232,CompanyX,False,"{'type': 'User', 'Id': '', 'Name': 'Joe Smith'}"
987654,CompanyY,True,"{'type': 'User', 'Id': '', 'Name': 'Mary Johnson'}"
Obviously I need to extract the key-value pair I want from the nested dictionary and assign that value to the higher-level dictionary. My question is how do I do that while still handling the simple values as is?
It seems like this could be done with dictionary comprehension, but I'm not sure I can do a conditional with that.
Alternatively I could go through each record, check each value to see if it's a dictionary, and write out the values I want to a new dictionary, but that feels a little too heavy.
Full disclosure: I'm new to Python, so apologies if I'm missing something obvious.
Thanks!
- Chris
If you don't need accounts for anything else you can do:
for account in accounts:
account['LastModifiedBy'] = account['LastModifiedBy']['Name']
otherwise, .copy() it and do the same.

Write list of dictionary values to file [duplicate]

This question already has answers here:
Write values of Python dictionary back to file
(2 answers)
Closed 7 years ago.
I have a list of dictionaries such as:
values = [{'Name': 'John Doe', 'Age': 26, 'ID': '1279abc'},
{'Name': 'Jane Smith', 'Age': 35, 'ID': 'bca9721'}
]
What I'd like to do is print this list of dictionaries to a tab delimited text file to look something like this:
Name Age ID
John Doe 26 1279abc
Jane Smith 35 bca9721
However, I am unable to wrap my head around simply printing the values, as of right now I'm printing the entire dictionary per row via:
for i in values:
f.write(str(i))
f.write("\n")
Perhaps I need to iterate through each dictionary now? I've seen people use something like:
for i, n in iterable:
pass
But I've never understood this. Anyone able to shed some light into this?
EDIT:
Appears that I could use something like this, unless someone has a more pythonic way (Perhaps someone can explain "for i, n in interable"?):
for dic in values:
for entry in dic:
f.write(dic[entry])
This is simple enough to accomplish with a DictWriter. Its purpose is to write column-separated data, but if we specify our delimiter to be that of tabs instead of commas, we can make this work just fine.
from csv import DictWriter
values = [{'Name': 'John Doe', 'Age': 26, 'ID': '1279abc'},
{'Name': 'Jane Smith', 'Age': 35, 'ID': 'bca9721'}]
keys = values[0].keys()
with open("new-file.tsv", "w") as f:
dict_writer = DictWriter(f, keys, delimiter="\t")
dict_writer.writeheader()
for value in values:
dict_writer.writerow(value)
f.write('Name\tAge\tID')
for value in values:
f.write('\t'.join([value.get('Name'), str(value.get('Age')), value.get('ID')]))
You're probably thinking of the items() method. This will return the key and value for each entry in the dictionary. http://www.tutorialspoint.com/python/dictionary_items.htm
for k,v in values.items():
pass
# assuming your dictionary is in values
import csv
with open('out.txt', 'w') as fout:
writer = csv.DictWriter(fout, fields=values.keys(). delimiter="\t")
writer.writeheader()
writer.writerow(values.values())

Making a raw dictionary sane

I have a dict brought in from a csv: {'0ca6f08e': '1111', '89b2e9ab': '2222', '0c2e5b6d': '3333', '07287d73': '4444'}
and what is needed is something like:
{'id' :'0ca6f08e', 'thing': '1111'}, {'id': '89b2e9ab', 'thing': '2222'}, {'id: '0c2e5b6d', 'thing': '3333'}
This is to bring order to the dict so I can operate later with sanity. I'm not clear on how to take a csv like:
0ca6f08e,1111
89b2e9ab,2222
0c2e5b6d,3333
an inject the keys for sanity and later use.
We can use a list comprehension to solve this:
>>> original = {'0ca6f08e': '1111', '89b2e9ab': '2222', '0c2e5b6d': '3333', '07287d73': '4444'}
>>> parsed = [{'id': key, 'thing': value} for key, value in a.items()]
>>> parsed
[{'thing': '1111', 'id': '0ca6f08e'}, {'thing': '2222', 'id': '89b2e9ab'}, {'thing': '3333', 'id': '0c2e5b6d'}, {'thing'
: '4444', 'id': '07287d73'}]
We're essentially grabbing each key and corresponding value in the original dict, and converting it into a list of dicts.
Note that it may be cleaner to just use the items method of a dict to grab the key and the value directly, and loop over that:
>>> original.items()
[('0ca6f08e', '1111'), ('89b2e9ab', '2222'), ('0c2e5b6d', '3333'), ('07287d73', '4444')]
If you are reading the file for the first time, you can fix the results like this:
with open('foo.csv') as f:
for line in f:
lines = [{'id': a, 'thing': b} for a,b in line.split(',')]
If you want to fix the results from the dictionary:
lines = [{'id': a, 'thing': b} for a,b in big_dict.iteritems()]
You can use the csv module's DictReader to read the csv file.
Here is an example:
import csv
with open('example.csv') as csvfile:
for csv_dict in csv.DictReader(csvfile, fieldnames=["id", "thing"])
# Now you can use the csv_dict as a normal dictionary
print csv_dict["id"]

Categories

Resources