Как создать json из двух списков в Python

#python #json

#python #json

Вопрос:

предположим, у меня есть два списка:

 table_headers = ['name', 'surname']
table_data = ['andrew', 'smith', 'bob', 'richardson']
  

как я могу сделать что-то подобное:

 json = {
    'name': ['andrew', 'bob'], 
    'surname': ['smith','richardson']
    }
  

Объяснение того, что я здесь делаю. Я разбираю таблицу html в json, я не нашел лучшего способа, чем создать два списка — один из заголовков, а другой — полные данные, а затем я собираюсь создать json из двух списков.

Комментарии:

1. Это dict содержащий sets . Вам нужен объект Python или строка в формате JSON? Кроме того, в названии вашего вопроса указано два dicts , но в теле указано два lists .

2. Форматы как входных, так и желаемых выходных данных вызывают у вас проблемы. Возможно, вам захочется переопределить тогда.

3. Я анализирую таблицу html, и мне нужно представление этой таблицы в формате json

4. возможно, вам следует изменить функцию синтаксического анализа, и она должна создать словарь.

5. @tkmttldn существует проблема с вопросом .. поля «имя» и «фамилия» не являются объектами json.. я думаю, это должен быть dict / Array .

Ответ №1:

Вероятно, есть какая-то функция, itertools которая могла бы упростить ее.

Я разделяю данные на более мелкие части и использую zip(header, part) для создания пар (key, val), которые я добавляю в словарь

 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)
  

Результат

 {'name': ['andrew', 'bob'], 'surname': ['smith', 'richardson']}
  

РЕДАКТИРОВАТЬ: то же самое с 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)
  

РЕДАКТИРОВАТЬ: и с помощью 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))
  

Комментарии:

1. Черт, itertools снова на помощь!

Ответ №2:

предполагая, что гарантируется, что данные таблицы содержат нужное количество записей данных для создания четного количества строк (в соответствии с вашим количеством заголовков)

Вы можете использовать старый добрый пакет json и создать то, что вы хотите, с помощью

 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. это умный третий аргумент в срезе.

Ответ №3:

Вам нужно выполнить итерацию по table_data списку и, в качестве альтернативы, выбрать значения, которые будут добавлены в список для name , и для surname значений в вашем словаре будет список, содержащий все имена и фамилии

 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)
  

Вывод будет выглядеть следующим образом.

 {'name': ['andrew', 'bob'], 'surname': ['smith', 'richardson']}
  

Или

 table_data = ['andrew', 'smith', 'bob', 'richardson', 'joe', 'jonas', 'matt', 'davis']
#Output
#{'name': ['andrew', 'bob', 'joe', 'matt'], 
#'surname': ['smith', 'richardson', 'jonas', 'davis']}
  

Ответ №4:

Вы могли бы сделать это изначально (без какого-либо импорта или специальных функций) следующим образом:

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

добавьте больше данных:

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

добавьте больше столбцов заголовка:

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