I'm a python newbie and I need to read and manipulate elements from a json file, but I keep getting errors and I have no idea how to move forward. This is my code:
import json
with open('file.txt', 'r') as json_data:
d = json.load(json_data)
An example of the dataset:
[
{
'id': 1,
'name': 'a',
'city': 'Paris'
},
{
'id': 2,
'name': 'b',
'city': 'Mons'
},
{
'id': 3,
'name': 'c.',
'city': 'Leuven'
}
]
When I try to get only id or name, I get this error:
city = d['city']
TypeError Traceback (most recent call last)
in ()
----> 1 city = d['city']
TypeError: list indices must be integers or slices, not str
Then I tried this:
city = d[:]['city']
TypeError Traceback (most recent call last)
in ()
----> 1 city = d[:]['city']
TypeError: list indices must be integers or slices, not str
Any ideas? Thanks!
You more likely don't want to know the array index of the element you are looking for.
With some pythonic flavor, you can create tuples with a list comprehension like this:
arr = [(dict['id'], dict['city']) for dict in d]
The output would be
[(1, 'Paris'),
(2, 'Mons'),
(3, 'Leuven')]
Then, you have the possibility to get only specific items in your tuples if needed.
Ex:
arr = [(dict['id'], dict['city']) for dict in d if 's' in dict['city']]
which would return id and name for every entry that contain 's' in the city property.
As this is a dictionary within a list you must provide a list index before calling value by the key. This should work:
dict = d[0]
city = dict['city']
Or you can simply use:
city = d[0]['city']
You can write a loop to go through each object
final=[]
for obj in d:
final.append(obj['city'])
Or you can try using this
final = [obj['city'] for obj in d]
Or if you only need the first value then
print(d[0]['city'])
Output
'Paris'
Since your data is a list of dictionaries, you'll have to use the index value to get the data in the dictionary
Related
inputTuple = ({'mobile': '91245555555', 'email': 'xyz#gmail.com', 'name': 'xyz', 'app_registration': 1},)
print(type(inputTuple)) # <class 'tuple'>
my_dict = dict(inputTuple)
print(my_dict) #ValueError: dictionary update sequence element #0 has length 4; 2 is required
mobile = my_dict.get("mobile")
email = my_dict.get("email")
name = my_dict.get("name")
print(mobile)
print(email)
print(name)
how to get now each data from this tuple, first how to convert this to dict, i need to convert to dict and have to get all the key pair values,and not by using index values
Thanks for the answers
Do you just want
my_dict = inputTuple[0]
data = my_dict['mobile']
print(data)
inputTuple = ({'mobile': '91245555555', 'email': 'xyz#gmail.com', 'name': 'xyz', 'app_registration': 1})
In the question the inputTuple value ended with 'comma' which will make it as tuple and if we remove that it will be dict. and it worked in below way after change in question.
mobile = data.get("mobile", None)
Thanks for all
I have a question about how I can make this code work.
I have several json files, from which I must read information and store it in a pandas framework to export it later. The json files are pretty branched up and go something like this:
'TESTS' -> 'MEASUREMENTS' -> SeveralTestNames(For each of those keys there is a key 'Value') I need to get only the Values and save them.
My thought was, that I get the keys with the testnames, and then in a loop apply these names to the json.load()-method, but no matter what I try, it doesnt work.
import json
with open(file) as f:
data = json.load(f)
date = data['INFO']['TIME'][0:10]
time = data['INFO']['TIME'][11:]
t = data['TESTS']['MEASUREMENTS']
type = [*t]
value = []
i = 0
for x in type:
v = data['TESTS']['MEASUREMENTS'][type[i]]['RESULTS']
value.append(v)
i = i + 1
This just gives me 'TypeError: list indices must be integers or slices, not str', but when I remove the last bit with the ['RESULTS'], it gives me the keys of the tests, but i need the values from within them.
It seems you're overcomplicating this for yourself a bit.
I'm reproducing your json from your comments as best as I can since parts of it are not valid json.
data = {
'INFO': {
'TIME': ' ',
'VERSION' : ' '
},
'TESTS': {
'MEASUREMENTS': {
'Test1': {
'RESULTS': {
'VALUE': 147799000000
}
},
'Test2': {
'RESULTS': {
'VALUE': 147888278322
}
}
}
}
}
values = []
# this iterates over each dict within the MEASUREMENTS key
# dict.values() returns a view that you can iterate over
# of just the values
for measurement in data['TESTS']['MEASUREMENTS'].values():
values.append(measurement['RESULTS']['VALUE'])
print(values)
In your case it would be:
import json
with open(file) as f:
data = json.load(f)
values = []
for measurement in data['TESTS']['MEASUREMENTS'].values():
values.append(measurement['RESULTS']['VALUE'])
print(values)
I am trying to find if a string Date is present in a list of items. If Date is not present i want to get a null list.
Code
data = [['Organizations', 'Name', 'San Franciso', 11, 32],
['CreativeTeamRoles', 'Description', 'Music Director', 945, 959],
['Persons', 'FullName', 'Salonen', 5761, 5778],
['CreativeTeamRoles', 'Description', 'Conductor', 7322, 7331],
['SoloistRoles', 'Description', 'Piano', 7627, 7632],
['Performances', 'Starttime', '2:00PM', 8062, 8068],
['Performances', 'Date', '2021-05-07', 8247, 8252],
['Performances', 'Endtime', '7:30PM', 8262, 8268]]
output_list = [item for items in data for item in items if 'Date' in item]
Since it has both strings and integers i am getting an error
TypeError: argument of type 'int' is not iterable
try this:
[d for d in data if 'Date' in d]
As from the question,
It seems like you want the Boolean value of the presence of a given string inside a nested list, you can try like this, which returns only True and False
print(any([True for i in data if 'Data' in i else False]))
If you want the list that contains the given string, then -
print([*i for i in data if 'Data' in i])
tell me if this is okay for you...
I have a list of nested dictionaries that I want to get specific values and put into a dictionary like this:
vid = [{'a':{'display':'axe', 'desc':'red'}, 'b':{'confidence':'good'}},
{'a':{'display':'book', 'desc':'blue'}, 'b':{'confidence':'poor'}},
{'a':{'display':'apple', 'desc':'green'}, 'b':{'confidence':'good'}}
]
I saw previous questions similar to this, but I still can't get the values such as 'axe' and 'red'. I would like the new dict to have a 'Description', 'Confidence' and other columns with the values from the nested dict.
I have tried this for loop:
new_dict = {}
for x in range(len(vid)):
for y in vid[x]['a']:
desc = y['desc']
new_dict['Description'] = desc
I got many errors but mostly this error:
TypeError: string indices must be integers
Can someone please help solve how to get the values from the nested dictionary?
You don't need to iterate through the keys in the dictionary (the inner for-loop), just access the value you want.
vid = [{'a':{'display':'axe', 'desc':'red'}, 'b':{'confidence':'good'} },
{'a':{'display':'book', 'desc':'blue'}, 'b':{'confidence':'poor'}},
{'a':{'display':'apple', 'desc':'green'}, 'b':{'confidence':'good'}}
]
new_dict = {}
list_of_dicts = []
for x in range(len(vid)):
desc = vid[x]['a']['desc']
list_of_dicts.append({'desc': desc})
I have found a temporary solution for this. I decided to use the pandas dataframe instead.
df = pd.DataFrame(columns = ['Desc'])
for x in range(len(vid)):
desc = vid[x]['a']['desc']
df.loc[len(df)] = [desc]
so you want to write this to csv later so pandas will help you a lot for this problem using pandas you can get the desc by
import pandas as pd
new_dict = {}
df = pd.DataFrame(vid)
for index, row in df.iterrows() :
new_dict['description'] = row['a']['desc']
a b
0 {'display': 'axe', 'desc': 'red'} {'confidence': 'good'}
1 {'display': 'book', 'desc': 'blue'} {'confidence': 'poor'}
2 {'display': 'apple', 'desc': 'green'} {'confidence': 'good'}
this is how dataframe looks like a b are column of the dataframe and your nested dicts are rows of dataframe
Try using this list comprehension:
d = [{'Description': i['a']['desc'], 'Confidence': i['b']['confidence']} for i in vid]
print(d)
I am using Jupyter Notebook and Python 3.4. I have a data structure in the format:
[{'AccountNumber': N,
'Amount': '0',
'Answer': '12:00:00 PM',
'ID': None,
'Type': 'WriteLetters',
'Amount': '10',
{'AccountNumber': Y,
'Amount': '0',
'Answer': ' 12:00:00 PM',
'ID': None,
'Type': 'Transfer',
'Amount': '2'}]
The end goal is to write this out to CSV.
For the above example the output would look like:
AccountNumber, Amount, Answer, ID, Type, Amount
N,0,12:00:00 PM,None,WriteLetters,10
Y,2,12:00:00 PM,None,Transfer,2
Below is the function that I am using to write out this data structure. Please excuse any indentation formatting issues. The data structure is returned through the function construct_results(get_just_xml_data). The data that is returned is in the format as above. construct_headers(get_just_xml_data) returns a list of headers. Writing out the row for headers_list works.
The list comprehension data is to remove duplicates and maintain the integrity of the column headers and the values for each new instance of the data structure (where the keys in the dictionary are the headers and values - row instances). The keys in this specific data structure are meant to check if there is a value instance, and if there is not - place an ''.
def write_to_csv(results, headers):
headers = construct_headers(get_just_xml_data)
results = construct_results(get_just_xml_data)
headers_list = list(headers)
with open('real_csv_output.csv', 'wt') as f:
writer = csv.writer(f)
writer.writerow(headers_list)
for row in results:
data = [row.get(index, '') for index in results]
writer.writerow(data)
However, when I run this, I receive this error:
The end goal is to write this out to CSV.
For the above example the output would look like:
AccountNumber, Amount, Answer, ID, Type, Amount
N,0,12:00:00 PM,None,WriteLetters,10
Y,2,12:00:00 PM,None,Transfer,2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-744-7746797fc9a5> in <module>()
----> 1 write_to_csv(results, headers)
<ipython-input-743-c822437eeaf0> in write_to_csv(results, headers)
9 writer.writerow(headers_list)
10 for item in results:
---> 11 data = [item.get(index, '') for index in results]
12 writer.writerow(data)
<ipython-input-743-c822437eeaf0> in <listcomp>(.0)
9 writer.writerow(headers_list)
10 for item in results:
---> 11 data = [item.get(index, '') for index in results]
12 writer.writerow(data)
TypeError: unhashable type: 'dict'
I welcome any feedback on what may be the cause.
You can use csv.DictWriter() to do this a little more easily:
with open('real_csv_output.csv', 'wt') as f:
csvw = csv.DictWriter(f, fieldnames=results[0].keys())
csvw.writeheader()
csvw.writerows(results)
BTW the error you are getting is because row is a string... You probably meant item.get() instead.
I went back to the drawing board:
These are my findings:
The ‘for’ statement iterates over ‘results’, getting an item each time.
The name ‘row’ is bound to each item in turn.
Then, each time through the ‘for’ loop, I iterate again over
‘results’. The name ‘index’ is bound to each item.
I then attempt to use the dict (each item from ‘results’ is itself a
dict) as a key into that same dict. A dict is not a valid key; it is not
a “hashable type” i.e. a type with a fixed value, that can produce a
hash of the value).
So I was getting dicts and attempting to use those dicts as keys into
dicts. That will give the error “TypeError: unhashable type: 'dict'”.
I wanted not the items from the original sequence, but the
keys from the mapping::
for input_record in results:
output_record = [input_record.get(key, "") for key in input_record]
But I've then throwing away the constructed list, since I do nothing
with it before the end of the loop.
`writer.writerow(data)`
This statement occurs only after all the items from ‘results’ have
been iterated. You will only have the most recent constructed row.
I wanted the following:
for input_record in results:
output_record = [input_record.get(key, "") for key in input_record]
writer.writerow(output_record)