Группировка полей словаря вместе Python - PullRequest
0 голосов
/ 05 июля 2018

Итак, у меня есть этот словарь в качестве вывода из разных запросов:

[{"qty": 12}, {"qty": 12}, {"qty": 12}, {"qty": 12}, {"qty": 12},
{"qty": 12}, {"fail": 0, "pass": 12}, {"fail": 0, "pass": 12},
{"fail": 1}, {"pass": 11}, {"fail": 1}, {"pass": 11}, {"fail": 1},
{"pass": 11}, {"fail": 2}, {"pass": 10}]

причина этого в том, что каждый из 'qty', 'pass' и 'fail' имеет разные запросы и добавляется в массив.

Можно ли как-нибудь сгруппировать все это и поместить в эту форму? в зависимости от их индексов?

[{"qty": 12, "fail": 0, "pass": 12}, {"qty": 12, "fail": 0, "pass":
12}, {"qty": 12, "fail": 1, "pass": 11}, {"qty": 12, "fail": 1,
"pass": 11}, {"qty": 12, "fail": 1, "pass": 11}, {"qty": 12, "fail":
2, "pass": 10}]

Заранее большое спасибо.

Ответы [ 3 ]

0 голосов
/ 05 июля 2018

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

Например:

list1 = [{"qty": 12}, {"qty": 12},]
list2 = [{"fail": 0, "pass": 12}, {"fail": 0, "pass": 12},]

map(lambda (ix, el): el.update(list2[ix]), enumerate(list1))

Теперь list1 будет содержать [{"qty": 12,"fail": 0, "pass": 12},... ]

0 голосов
/ 05 июля 2018

ОБНОВЛЕНИЕ

Спасибо за напоминание UltraInstinct и Mankind_008 , более упрощенный и внутренний ответ рассматривается ниже:

lst = [{"qty": 12}, {"qty": 12}, {"qty": 12}, {"qty": 12}, {"qty": 12}, {"qty": 12}, {"fail": 0, "pass": 12},
       {"fail": 0, "pass": 12}, {"fail": 1}, {"pass": 11}, {"fail": 1}, {"pass": 11}, {"fail": 1}, {"pass": 11},
       {"fail": 2}, {"pass": 10}]

# separate dictionaries with different keys
# dictionaries containing both "fail" and "pass" keys will be split
# and fitted into "fail_group" and "pass_group" respectively
qty_group = ({key: _} for dic in lst for key, _ in dic.items() if key == "qty")
fail_group = ({key: _} for dic in lst for key, _ in dic.items() if key == "fail")
pass_group = ({key: _} for dic in lst for key, _ in dic.items() if key == "pass")

# merge dictionaries with keys "qty", "fail" and "pass" item-wisely.
# and print result 
print(list({**x, **y, **z} for (x, y, z) in zip(qty_group, fail_group, pass_group)))

Обратите внимание, что {**x, **y, **z} работает только на python> = 3.5, который был введен в PEP 448 . Для python 2 или python <3.5 вы должны определить свою пользовательскую функцию, чтобы она делала то же самое, что и <code>{**x, **y, **z} (подробности обсуждаются в этой теме ):

def merge_three_dicts(x, y, z):
    m = x.copy()
    n = y.copy()
    z.update(x)
    z.update(y)
    return z

Таким образом, в этом сценарии последняя строка кода должна быть:

print(list(merge_three_dicts(x, y, z) for (x, y, z) in zip(qty_group, fail_group, pass_group)))

Оба вышеупомянутых метода дадут вам результат:

[{'qty': 12, 'fail': 0, 'pass': 12}, {'qty': 12, 'fail': 0, 'pass': 12}, {'qty': 12, 'fail': 1, 'pass': 11}, {'qty': 12, 'fail': 1, 'pass': 11}, {'qty': 12, 'fail': 1, 'pass': 11}, {'qty': 12, 'fail': 2, 'pass': 10}]
0 голосов
/ 05 июля 2018

Это ваш список словарей. У некоторых [fail, pass] в качестве ключей, у некоторых просто [fail] или просто [pass] в качестве ключей. Не знаю, предназначено ли это.

dictList = [{"qty": 12}, {"qty": 12}, {"qty": 12}, {"qty": 12}, {"qty": 12},
{"qty": 12}, {"fail": 0, "pass": 12}, {"fail": 0, "pass": 12},
{"fail": 1}, {"pass": 11}, {"fail": 1}, {"pass": 11}, {"fail": 1},
{"pass": 11}, {"fail": 2}, {"pass": 10}]

Мой код начинается здесь

failpassList = [] #To keep track of `["fail", "pass"]`
qtyList = [] #To keep track of `["qty"]`

tempDict = {}
checkNext = 0

for index in range(0, len(dictList)):

    #This is the case when, I've seen a key called `fail`, 
    #and now I'm seeing a `pass` right after `fail`, so I will 
    #bring `fail` and `pass` together as keys of a single dictionary.
    #Once this is done, it to `failpassList`

    if checkNext == 1:
        if list(dictList[index].keys()) == ['pass']:
            tempDict.update(dictList[index])
            failpassList.append(tempDict)
            tempDict = {}
            checkNext = 0


    #If the key is `['fail', 'pass']`, then it is correctly 
    #structured, I can append it to `failpassList`.

    elif list(dictList[index].keys()) == ['fail', 'pass']:

        failpassList.append(dictList[index])

    #If the key is `fail` alone, then wait for the next `pass`.
    #I have done this by incrementing a variable called `checkNext`

    elif list(dictList[index].keys()) == ['fail']:

        checkNext += 1
        tempDict = dictList[index]

    #If the key is `qty` put it in a separate list
    else:
        qtyList.append(dictList[index])

Так как qtyList и failpassList будут одинаковой длины, Я просматриваю один из них и обновляю словарь соответственно.

for i in range(0, len(qtyList)):

    qtyList[i].update(failpassList[i])

print(qtyList)

даст:

[{'qty': 12, 'fail': 0, 'pass': 12}, {'qty': 12, 'fail': 0, 'pass': 12}, 
{'qty': 12, 'fail': 1, 'pass': 11}, {'qty': 12, 'fail': 1, 'pass': 11}, 
{'qty': 12, 'fail': 1, 'pass': 11}, {'qty': 12, 'fail': 2, 'pass': 10}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...