LINUX.ORG.RU

Генерация вложенный словарей

 


0

1

Доброго времени суток, ЛОР:)

Начал изучать python и столкнулся в такой нетривиальной для меня проблемой.

Нужно реализовать словарь со вложениями следующего вида:

cards = {
"opened" : { "%s" % str(random.randrange(100,500,100)) : randint(0,13) },
"closed" : {
"%s" % str(random.randrange(100,500,100)) : randint(0,13),
"%s" % str(random.randrange(100,500,100)) : randint(0,13),
"%s" % str(random.randrange(100,500,100)) : randint(0,13),
....
n},
"fantom" : { "%s" % str(random.randrange(100,500,100)) : randint(0,13) }
        }

Т.е. нужно, чтобы создавалась вложенная структура «closed» n раз. Вопрос каким образом лучше сгенерировать вышеприведённую структуру?

Мои мысли блуждаю где-то около этого:

cards = {
            "opened" : { "%s" % str(random.randrange(100,500,100)) : randint(0,13) },
            "closed" : {},
            "fantom" : { "%s" % str(random.randrange(100,500,100)) : randint(0,13) }
        }
i=0
        while i <= n:
            cards["closed"] += { ("%s" % str(random.randrange(100,500,100))) : randint(0,13) }
            i += 1

Но такой вариант не работает(. Помогите новичку, plz:)

Заранее спасибо.



Последнее исправление: Sektor (всего исправлений: 2)
Ответ на: комментарий от Siado

Ты не понял. Мне в итоге нужно получить структуру вида:

cards (примерный образец)

{ 
  "opened" : {"300":7},
  "closed" : {"100":2, "400":10, "200":7, ... n},
  "fantom" : {"200" : 5}
}

Проблема в том, что в такой структуре «closed» - словарь, а к словарю я не могу применить метод append.

Sektor
() автор топика
cards = {
"opened" : { "%s" % str(random.randrange(100,500,100)) : randint(0,13) },
"closed" : dict(((str(random.randrange(100,500,100)), randint(0,13)) for i in xrange(n))),
"fantom" : { "%s" % str(random.randrange(100,500,100)) : randint(0,13) }
        }
anonymous
()
Ответ на: комментарий от Sektor

А так?

cards = {
            "opened" : [ randint(0,13) ],
            "closed" : [],
            "fantom" : [ randint(0,13) ],
        }

for i in range(n):
    cards["closed"].append([random.randrange(100,500,100)), randint(0,13)])
Siado ★★★★★
()
Ответ на: комментарий от anonymous

Спасибо. Вроде бы работает. dict(), как я понял, создаёт словарь?

Sektor
() автор топика
Ответ на: комментарий от Siado

Это немного не то, что мне было нужно. Ваш код создаёт структуру из списков[]. А мне была нужна вложенная структура из словарей{}. Это немного разные вещи. И методы, применяемые к ним тоже не одинаковы:)

Sektor
() автор топика
Ответ на: комментарий от Sektor

Т.е. у тебя предусмотрен тот вариант, что ключи с одинаковым названием попросту перезаписываются?

Siado ★★★★★
()

Забавно) Как теперь сравнить два словаря?

Например, есть: args={«100», 10}

Его нужно сравнить со всеми значениями ключей cards[«closed»]. Как реализовать такую жуть?

Sektor
() автор топика
Ответ на: комментарий от Sektor

Так вот такое со словарями не прокатит. В данном случае самый простой вариант использовать двумерный массив.

Siado ★★★★★
()
cards = {
            "opened" : { "%s" % str(random.randrange(100,500,100)) : randint(0,13) },
            "closed" : {},
            "fantom" : { "%s" % str(random.randrange(100,500,100)) : randint(0,13) }
        }
i=0
        while i <= n:
            cards["closed"][("%s" % str(random.randrange(100,500,100)))] = randint(0,13)
            i += 1

В чем глубинный смысел конcтрукции

("%s" % str(random.randrange(100,500,100)))
я не понял, это то же самое что и
str(random.randrange(100,500,100))

А вообще прежде чем кодить надо сформулировать задачу словами.

AIv ★★★★★
()
Последнее исправление: AIv (всего исправлений: 1)

Если ты хотел добавить элементы в цикле к словарю под ключом 'closed', можно было использовать:

for i in xrange(n):
	cards['closed'][str(randrange(100,500,100))] = randint(0,13)
Правда в этом случае все случайно повторенные ключи при генерации затрут старые значения и в cards['closed'] будет меньше n элементов. Подозреваю это не то, что тебе нужно, и как сказал Siado, для хранения таких вещей лучше использовать массивы (или списки).
for i in xrange(n):
	rand_str = str(randrange(100,500,100))
	m = randint(0,13)
	if rand_str in cards['closed']:
		# добавляем к списку значение, если он уже существует
		cards['closed'][rand_str] += [m]
	else:
		# создаем новый список, если его еще нет
		cards['closed'][rand_str] = [m]

На выходе имеем

{'opened': {'100': 5}, 'closed': {'200': [12, 4], '100': [5], '400': [11, 13]}, 'fantom': {'200': 12}}

Не очень понятно, зачем используются строки как ключи словаря ('100', '300' и т.д.), целые сами по себе будут отличными ключами.

Его нужно сравнить со всеми значениями ключей cards[«closed»]. Как реализовать такую жуть?

for key, value in cards['closed'].iteritems():
	...
Ableto
()
Ответ на: комментарий от Ableto

вообще то есть метод dict.setdefault для такого добавления:

for i in xrange(n):
  ...
  cards['closed'].setdefault(rand_str, []).append(m)
не надо так много букв, да и работает существенно быстрее;-)

AIv ★★★★★
()
Ответ на: комментарий от AIv

Только особого смысла нет ни в setdefault, ни в if/else, т.к. словарь определяется заблаговременно и ничего не мешает создать в нем пустой список =)

Siado ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.