2

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.

5
  • That is a dict containing sets. Do you want a Python object, or a JSON-formatted string? Also, your question title says two dicts, but the body says two lists. Commented Apr 22, 2019 at 5:34
  • The formats of both the input and the desired output are asking for making you troubles. You might want to redefine then. Commented Apr 22, 2019 at 5:41
  • I am parsing html table, and I need a json representation of this table Commented Apr 22, 2019 at 5:42
  • maybe you should change parsing function and it should create dictionary. Commented Apr 22, 2019 at 5:50
  • @tkmtldn there is an issue with the question..'name' and 'surname' fields are not json objects.. i guess it should be dict / Array. Commented Apr 22, 2019 at 5:53

4 Answers 4

3

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))
Sign up to request clarification or add additional context in comments.

1 Comment

Damn, itertools to the rescue again!
1

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)

1 Comment

it is clever - third argument in slice.
0

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']}

Comments

0

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.']}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.