Reputation: 23
assume I have two lists:
table_headers = ['name', 'surname']
table_data = ['andrew', 'smith', 'bob', 'richardson']
how can I make something like this:
json = {
'name': ['andrew', 'bob'],
'surname': ['smith','richardson']
}
Explanation of what am I doing here. I am parsing an html table to json, I didnt find the better way than to make a two lists - one is headers and one is full data and then Im gonna make a json from two lists.
Upvotes: 2
Views: 2751
Reputation: 945
You could do this natively (without any imports or special functions) as follows:
table_headers = ['name', 'surname']
table_data = ['andrew', 'smith', 'bob', 'richardson']
num_of_cols = len(table_headers)
cols = [[x for x in table_data[i::num_of_cols]] for i in range(num_of_cols)]
print(dict(zip(table_headers, cols)))
## {'name': ['bob', 'andrew'], 'surname': ['smith', 'richardson']}
add more data:
table_data.extend(['john', 'doe'])
cols = [[x for x in table_data[i::num_of_cols]] for i in range(num_of_cols)]
print(dict(zip(table_headers, cols)))
## {'name': ['andrew', 'bob', 'john'], 'surname': ['smith', 'richardson', 'doe']}
add more header columns:
table_headers = ['name', 'surname', 'middle_initial']
table_data = ['andrew', 'smith', 'a.','bob', 'richardson', 'b.']
num_of_cols = len(table_headers)
cols = [[x for x in table_data[i::num_of_cols]] for i in range(num_of_cols)]
print(dict(zip(table_headers, cols)))
## {'name': ['andrew', 'bob'], 'surname': ['smith', 'richardson'], 'middle_initial': ['a.', 'b.']}
Upvotes: 0
Reputation: 4839
assuming that it is guaranteed the table data has the right amount of data entries to create an even number of rows (according to your header count)
You can use the good old json package, and create what you want by
import json
# a very nice python package
d = {header: table_data[i::len(table_headers)] for i,header in
enumerate(table_headers)}
return json.dumps(d)
Upvotes: 1
Reputation: 142651
Probably there is some function in itertools
which could make it simpler.
I split data in smaller parts and use zip(header, part)
to create pairs (key, val) which I addd to dictionary
table_headers = ['name', 'surname']
table_data = ['andrew', 'smith', 'bob', 'richardson']
len_headers = len(table_headers)
len_data = len(table_data)
result = dict()
for x in range(0, len_data, len_headers):
for key, val in zip(table_headers, table_data[x:x+len_headers]):
if key not in result:
result[key] = []
result[key].append(val)
print(result)
Result
{'name': ['andrew', 'bob'], 'surname': ['smith', 'richardson']}
EDIT: the same with itertools.cycle()
import itertools
table_headers = ['name', 'surname']
table_data = ['andrew', 'smith', 'bob', 'richardson']
result = dict()
for key, val in zip(itertools.cycle(table_headers), table_data):
if key not in result:
result[key] = []
result[key].append(val)
print(result)
EDIT: and with defaultdict()
import itertools
import collections
table_headers = ['name', 'surname']
table_data = ['andrew', 'smith', 'bob', 'richardson']
result = collections.defaultdict(list)
for key, val in zip(itertools.cycle(table_headers), table_data):
result[key].append(val)
print(result)
import json
print(json.dumps(result))
Upvotes: 3
Reputation: 20490
You need to iterate over the table_data
list, and alternatively pick values to be added to a list for name
, and for surname
, the values in your dictionary will be a list to contain all names and surnames
table_headers = ['name', 'surname']
table_data = ['andrew', 'smith', 'bob', 'richardson']
dct = {}
idx = 0
for data in table_data:
key = table_headers[idx]
#Create value as a list
if key in dct.keys():
dct[key].append(data)
else:
dct[key] = [data]
#We need to make sure index of list rolls over to pick the correct element in table_data
idx = int((idx+1)%2)
The output will look like.
{'name': ['andrew', 'bob'], 'surname': ['smith', 'richardson']}
Or
table_data = ['andrew', 'smith', 'bob', 'richardson', 'joe', 'jonas', 'matt', 'davis']
#Output
#{'name': ['andrew', 'bob', 'joe', 'matt'],
#'surname': ['smith', 'richardson', 'jonas', 'davis']}
Upvotes: 0