Составьте пустые списки и добавьте все подключи словаря

У меня есть словарь, в котором есть дополнительный словарь:

d ={10L: {u'Owner Name': u'abc', u'Email': u'wa@gmail.com', u'Manager Name': u'jhon'}, 12L: {u'Owner Name': u'awdaw', u'Email': u'raghavpatnecha15@gmail.com', u'Manager Name': u'raghav'}}

Итак, когда я использую d[10][Owner Name], я получаю abc. Но этот шаблон повторяется, я имею в виду, что каждый вложенный словарь имеет одни и те же подключи и каждый вложенный словарь имеет одинаковую длину относительно. Итак, если я добавлю несколько параметров в подпункт с id=10, я добавлю те же параметры к другим ключам.

Теперь мой вопрос заключается в том, что каждый раз, когда элемент в моем вложенном слове увеличивается, я должен составлять пустой список и добавлять его значения в этот список следующим образом:

def getcontacts():
    id = [10, 12]
    Owner_names = []
    Emails = []
    Manager_Names = []  # to add more columns just add an empty list
    for j in id:
        Owner_names.append(d[j]['Owner Name'])
        Emails.append(d[j]['Email'])
        Manager_names.append(d[j]['Manager Name'])  # append to list
    return Owner_names, Emails, Manager_Names

names, emails, managers = get_contacts()

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

Есть ли способ автоматизировать этот процесс? Итак, если у меня есть имя подключа Product Name, моя функция может автоматически создать пустой список Product_Names и добавить его, как Product_names.append(d[j]['Product Name']), а затем вернуть его, когда я вызываю получение контактов:

Owner_names, emails, Manager_Name, Product Names = get_contacts().

Возможно ли, чтобы я мог написать функцию, которая:

  1. Подсчитайте подключи в моем словаре и сделайте пустой список, поместив s в качестве пост-исправления.

  2. Добавьте соответствующие значения в список и добавьте его в оператор возврата.

Обновлять

Будет ли решение defaultdict по-прежнему полезным, если я хочу контролировать, какие значения использовать. В настоящее время я делаю это:

for name, email, manager in zip(names, emails, managers):
         print name, email , manager
         message = message_template.substitute(PERSON_NAME=name.title(),MANAGER_NAME=manager.title())

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

l1 = [u'abc', u'awdaw']
l2 = [u'jhon', u'raghav']
for name1,name2 in zip(l1,l2):
    print name1, name2

Но я не могу заархивировать словарь по понятным причинам. Как dict по умолчанию может помочь мне в выборе значений, которые я хочу использовать. Итак, я не хочу включать Owner_Name, я бы просто пропустил это в этой строке:

message = message_template.substitute(MANAGER_NAME=manager.title())

Ответ Бруно Дестюилье поможет. Если вам не обязательно работать со словарями, вы также можете взглянуть на фреймы данных. import pandas as pd; df = pd.DataFrame(d).T

Uvar 11.04.2018 13:48

Затем вам нужно посмотреть на заказанный диктатор (поищите его вокруг). Причина в том, что обычный dict будет возвращать значения / ключи в порядке, который вы не контролируете (и вы хотите эту динамику). Но подумайте об этом ... вы добавляете ключ к data dict и хотите, чтобы он был возвращаемым параметром, но вы не спрашиваете свою функцию, куда его поместить!

Will 11.04.2018 14:25

«Будет ли решение defaultdict по-прежнему полезным, если я хочу иметь контроль над тем, какие значения использовать» => ну да, конечно, почему ???

bruno desthuilliers 11.04.2018 14:37
2
3
639
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

    d ={10: {'Owner Name': 'abc', 'Email': 'wa@gmail.com', 'Manager Name': 'jhon'}, 
        12: {'Owner Name': 'awdaw', 'Email': 'raghavpatnecha15@gmail.com', 'Manager Name': 'raghav'}}
    from collections import defaultdict
    def get_contacts():
        data = defaultdict(list)
        for key, val in d.items():
            for key1, val1 in val.items():
                data[key1 + 's'].append(val1)
        return data.values()
    names, emails, managers = get_contacts()
    >>>print(names, emails, managers)
       (['abc', 'awdaw'],['wa@gmail.com', 'raghavpatnecha15@gmail.com'],
        ['jhon', 'raghav'])

Dicts неупорядочены, поэтому вы не можете полагаться на порядок dict.values(). Кроме того, возвращение значений означает только то, что вам нужно обновлять LHS вызова get_contacts() каждый раз, когда что-то добавляется к дублированным диктаторам.

bruno desthuilliers 11.04.2018 13:43
Ответ принят как подходящий

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

from collections import defaultdict

def get_contacts():
    id = [10, 12]
    results = defaultdict(list)
    for j in id:
        obj = d[j]
        for key, value in obj.items():
            results[key].append(value)
    return results

results = get_contacts()
for k, v in results.items():
    print("{} : {}".format(k, v))

Как правило: когда вы думаете, что вам нужны «динамические имена», вам действительно нужен диктант.

РЕДАКТИРОВАТЬ:

names, emails, managers = get_contacts()
for name, email, manager in zip(names, emails, managers):
    # ...

=>

results = get_contacts()
names, emails, managers = results["Owner Name"], results['Manager Name'], results["Email"]
for name, email, manager in zip(names, emails, managers):
    # ...

defaultdict. да. лучше, чем у меня :)

Will 11.04.2018 13:53

Это подойдет. Но дело в том, что когда я вызываю get_contacts (), я получаю отдельные списки. Используя что и делаю. for name, email, manager in zip(Owner_names, Emails, Manager_Names):, и я называю его как message_template.substitute(PERSON_NAME=name.title(),MANAGER‌​_NAME=manager.title(‌​)). Как я могу это сделать, используя dict по умолчанию. Потому что мне все еще нужен контроль над количеством ключей, которые я использую

Raghav Patnecha 11.04.2018 13:54

@bruno desthuilliers, пожалуйста, посмотрите обновление

Raghav Patnecha 11.04.2018 14:19

«Но дело в том, что когда я вызываю get_contacts (), я получаю отдельные списки» => вы все равно получаете отдельные списки. Единственное отличие состоит в том, что они теперь называются results["Owner Name"] вместо names и т.д. ... И ничто не мешает вам привязать их к любому имени, которое вам нравится, например, names = results["Owner Name"] (см. Мой отредактированный ответ).

bruno desthuilliers 11.04.2018 14:35
data ={10L: {u'Owner Name': u'abc', u'Email': u'wa@gmail.com', u'Manager Name': u'jhon'}, 
       12L: {u'Owner Name': u'awdaw', u'Email': u'raghavpatnecha15@gmail.com', u'Manager Name': u'raghav'}}

def get_contact(data, ids):
    ret_data = {}
    for i in ids:
        sub_data = data.get(i)
        for k in sub_data.keys():
            ret_data[k] = ret_data.get(k, [])
            ret_data[k].append(sub_data[k])

    # Doing this will have unordered results so one would have to
    # throw data into an OrderedDict (from a 3rd party lib like boltons)
    # return [ret_data[k] for k in ret_data.keys()]

    # so make sense to return the dict
    return ret_data

Udpate: Итак, вы хотите, чтобы возвращаемые данные были упорядочены так, как вы ожидаете. Что ж, тогда вам нужно сообщить своим «data» ключам, в каком порядке вы их ожидаете.

def get_contact(data, ids):
ret_data = {}
for i in ids:
    sub_data = data.get(i)
    for k in sub_data.keys():
        ret_data[k] = ret_data.get(k, [])
        ret_data[k].append(sub_data[k])

return [ret_data[k] for k in sorted(ret_data.keys())]

Я также предпочитаю использовать dict по умолчанию, но проблема в том, что и вы, и @Bruno Desthuilliers возвращаете результаты в виде словаря. Но что я делаю дальше в сценарии, так это то, что я архивирую списки: for name, email, manager in zip(names, emails, managers): и делаю этот message = message_template.substitute(PERSON_NAME=name.title(),MANAGER‌​_NAME=manager.title(‌​)) таким образом, я мог бы иметь больший контроль над тем, какие значения мне нужны. Как я мог сделать это в твоем словаре

Raghav Patnecha 11.04.2018 14:07

Вы просите get_contacts динамически возвращать вам значения из ключей. Вы не говорите get_contacts, в каком порядке вы ожидаете, что они вернутся к вам. По крайней мере, dict позволяет вам опросить эту структуру. Поэтому либо используйте orderdict, либо добавьте в свою структуру ключ «orderby», чтобы вы могли явно вернуть то, что ожидаете.

Will 11.04.2018 14:27

Другие вопросы по теме