2013-05-02 3 views
0

Что я хочу сделать, так это определить три очень похожих словаря с едва различимыми различиями. Если вы это признаете, это одна из проблем курса Codeacademy на Python, и я хочу сделать это немного более элегантно. В любом случае, вот что у меня есть:Определение нескольких словарей в петле в Python

import string 
for name in ["lloyd", "alice", "tyler"]: 
    name = {"name": string.capitalize(name), "homework": [], "quizzes": [], "tests": []} 

Это не работает. Я хочу три словаря, которые имеют имена «lloyd» «alice» и «tyler» и с ключами их имен (но с заглавной буквы), «домашняя работа», «викторины» и «тесты»

Чтобы уточнить , выход я хочу эквивалентно следующему:

lloyd = {"name": "Lloyd", "homework": [], "quizzes": [], "tests": []} 
alice = {"name": "Alice", "homework": [], "quizzes": [], "tests": []} 
tyler = {"name": "Tyler", "homework": [], "quizzes": [], "tests": []} 
+1

В зависимости от ваших потребностей и предпочтений вы также можете создать новый класс для представления студентов с атрибутами «имя», «домашнее задание» и т. Д., А также методы/функции для работы с этой информацией. Но словари прекрасны, поэтому нет недовольства там, пока у ваших учеников есть уникальные имена :) – mdscruggs

+0

* Почему вы импортируете 'string'? Функции в этом модуле были в основном устаревшими в * python 1.6 * или что-то в этом роде. Вместо этого вы должны использовать методы строковых объектов. – Bakuriu

ответ

3

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

>>> names=["lloyd", "alice", "tyler"] 
>>> keys=["homework", "quizzes", "tests"] 
>>> dic={ name.capitalize():{ key:[] for key in keys} for name in names} 
>>> dic 
{'Tyler': {'quizzes': [], 'tests': [], 'homework': []}, 
'Lloyd': {'quizzes': [], 'tests': [], 'homework': []}, 
'Alice': {'quizzes': [], 'tests': [], 'homework': []}} 

Теперь доступ Tyler просто использовать:

>>> dic['Tyler'] 
{'quizzes': [], 'tests': [], 'homework': []} 
0

Ваш код работает для меня, оставляя один dict в конце имени name с последним именем в списке имен в качестве значения по 'name'. Может быть, вы хотите добавить все списки name в список?

all_dicts = [] 

for name in names: 
    name = {yadda yadda} 
    all_dicts.append(name) 

Или даже создайте новый dict, а затем установите ключ этого нового dict на имена, вытащенные из списка.

0

В python вы не можете создать local переменные во время выполнения. Вы должны явно присвоить им значение.

Что-то вроде этого:

locals()['lloyd'] = {...} 
locals()['alice'] = {...} 
locals()['tyler'] = {...} 

делает не создать локальные переменныеlloyd, alice и tyler:

>>> def some_function(): 
...  locals()['lloyd'] = {} 
...  print lloyd 
... 
>>> some_function() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in some_function 
NameError: global name 'lloyd' is not defined 

Цитирование из документации для locals():

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

Что вы можете сделать, это создать глобальные переменные во время выполнения, используя словарь, возвращенное globals(). Хотя я не понимаю, почему вы должны сделать что-то подобное.

Однако вы можете использовать copy модуль, чтобы избежать повторений dict определения:

import copy 
base_dict = {"homework": [], "quizzes": [], "tests": []} 
lloyd = copy.deepcopy(base_dict) 
alice = copy.deepcopy(base_dict) 
tyler = copy.deepcopy(base_dict) 
for the_dict, name in ((lloyd, "lloyd"), (alice, "alice"), (tyler, "tyler")): 
    the_dict["name"] = name.capitalize() 

Или без петли:

import copy 
base_dict = {"homework": [], "quizzes": [], "tests": []} 
lloyd = copy.deepcopy(base_dict) 
alice = copy.deepcopy(base_dict) 
tyler = copy.deepcopy(base_dict) 
lloyd["name"], alice["name"], tyler["name"] = "lloyd", "alice", "tyler" 

В зависимости от того, что вы хотите сделать с помощью defaultdict может быть хорошая идея:

from collections import defaultdict 
lloyd = defaultdict(list) 
alice = defaultdict(list) 
tyler = defaultdict(list) 
lloyd["name"], alice["name"], tyler["name"] = "lloyd", "alice", "tyler" 

defaultdict, вместо того, чтобы поднимать KeyError, когда ключ не найден, он создает значение по умолчанию (в этом случае пустое list) и устанавливает это значение как значение ключа, поэтому вам не нужно указывать "tests": [].

0

Что вам нужно, это не очень понятно

Если вы хотите словарей с ключами имена в ["lloyd", "alice", "tyler"], то это делает его

import string 
dictionaries = {} # dicts 
for name in ["lloyd", "alice", "tyler"]: 
    dictionaries[string.capitalize(name)]={"homework": [], 
     "quizzes": [], "tests": []} 

Результат

>>> dictionaries 
{'Tyler': {'quizzes': [], 'tests': [], 'homework': []}, 
'Lloyd': {'quizzes': [], 'tests': [], 'homework': []}, 
'Alice': {'quizzes': [], 'tests': [], 'homework': []}} 
+0

нет необходимости импортировать 'string', вы можете просто использовать' name.capitalize() '. –

0
class Student: 
    def __init__(self,name): 
     self.name=name.capitalize() 
     self.quizzes=[] 
     self.tests=[] 
     self.homework=[] 
#this 
Jane =Student('jane') 
JanesDict = Jane.__dict__ 
#or 
JimsDict = Student('jim').__dict__ 

prety много создает словарь для нового ученика с одной строкой.

Смежные вопросы