Как объединить словарь в списке с Python - PullRequest
0 голосов
/ 12 октября 2019

Я сгенерировал данные из формы с этим кодом:

time_schedule = []
f = request.form
for key in f.keys():
    for idx, value in enumerate(f.getlist(key), 1):
        time_schedule.append({key+str(idx): value})

Затем я получил этот результат, когда я print это:

[{'csrf_token1': 'Ijg2YWEyNDEwMWI3ZTE4NjYyNzBkNTEwYTZlMzRiYTM3MjY2ZTk2NDAi.XaGmZw.rMR9Q53hlAQV-Ul9X3PHT55TMxc'}, {'course_start_at1': '2019-10-26'}, {'schedule_day1': 'Sunday'}, {'schedule_day2': 'Saturday'}, {'start_at1': '01:00'}, {'start_at2': '03:00'}, {'end_at1': '02:00'}, {'end_at2': '04:00'}, {'step1': 'input_teacher_email'}]

Затем я удалил до неоправданного значения:

del time_schedule[0]
del time_schedule[0]
del time_schedule[-1]

Тогда я вот значение сейчас:

[{'schedule_day1': 'Sunday'}, {'schedule_day2': 'Saturday'}, {'start_at1': '01:00'}, {'start_at2': '03:00'}, {'end_at1': '02:00'}, {'end_at2': '04:00'}]

Теперь я хочу объединить это так:

[
    {'schedule_day1': 'Sunday', 'start_at1': '01:00', 'end_at1': '02:00'},
    {'schedule_day2': 'Saturday', 'start_at2': '03:00', 'end_at2': '04:00'},
]

Но не уверен, каксделать это в лучшей практике. Пожалуйста, любой ответ, источник или учебник, как это будет оценено.? :)

Ответы [ 3 ]

2 голосов
/ 12 октября 2019

Вы можете сделать:

import re
from collections import defaultdict

data = [
    {'schedule_day1': 'Sunday'},
    {'schedule_day2': 'Saturday'},
    {'start_at1': '01:00'},
    {'start_at2': '03:00'},
    {'end_at1': '02:00'},
    {'end_at2': '04:00'}
]


seen = defaultdict(dict)
for d in data:
    for name, value in d.items():
        key = re.search('(\d+)$', name).group()  # this is the key extractor
        seen[key][name] = value

result = list(seen.values())

print(result)

Вывод

[{'schedule_day1': 'Sunday', 'start_at1': '01:00', 'end_at1': '02:00'}, {'schedule_day2': 'Saturday', 'start_at2': '03:00', 'end_at2': '04:00'}]

Или поскольку вы пометили панд:

import pandas as pd   

df = pd.DataFrame(data=[item for d in data for item in d.items()], columns=['name', 'value'])
grouper = df.groupby(df.name.str.extract('(\d+)$').squeeze())
result = [dict(zip(group.name, group.value)) for _, group in grouper]
print(result)

Выходные данные

[{'schedule_day1': 'Sunday', 'start_at1': '01:00', 'end_at1': '02:00'}, {'schedule_day2': 'Saturday', 'start_at2': '03:00', 'end_at2': '04:00'}]

Ключ обоих подходов заключается в группировании по последним цифрам каждого ключа словарей, в первых решениях это делается с использованием словаря seen (фактически defaultdict , во втором - панды groupby .

1 голос
/ 12 октября 2019

Используйте мой код (введите данные в аргумент функции)

def merge(_list):
    my_list = [] #data my_list
    for data in _list: #foreach in _list
        pq = ''.join([a for a in data]) #get string
        try:
           number = int(pq[-1]) #get number of last string (schedule1 -> 1)
        except:
           print("List can't be decoded")
        try:
           my_list[number-1] += [data]
        except:
           my_list.append([data])
    for x in range(len(my_list)):
        sub = {} #data sub
        for n in my_list[x]:
            sub.update(n) #update dictionary n
        my_list[x] = sub
    return my_list #returning my_list

Это немного дольше, потому что это очень сложный алгоритм без какого-либо модуля.

Чтобы использовать это merge функция

data = [{'schedule_day1': 'Sunday'}, {'schedule_day2': 'Saturday'}, {'start_at1': '01:00'}, {'start_at2': '03:00'}, {'end_at1': '02:00'}, {'end_at2': '04:00'}]
data = merge(data)
print(data) 
#print out [{'schedule_day1': 'Sunday', 'start_at1': '01:00', 'end_at1': '02:00'}, {'schedule_day2': 'Saturday', 'start_at2': '03:00', 'end_at2': '04:00'}]
1 голос
/ 12 октября 2019

Таким образом, после вашего редактирования ситуация выглядит следующим образом:

  • для каждого ключа, который вы проходите через значения этого ключа
  • , где значения сортируются соответственно
  • в основном вы отсортировали списки значений по ключу

Моя попытка состоит в том, чтобы не связывать индекс со строкой, а продолжать использовать его в качестве индекса.

sched = {}
for key in f.keys():
    for idx, value in enumerate(f.getlist(key), 1):
        if idx not in sched:
            sched[idx] = {}
        sched[idx][key] = value

Это должно дать вам указание, где ключ - это ваш восходящий индекс, а значение - это то, что вам нужно. Если вам нужен список, вы можете преобразовать его в один ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...