2013-12-12 1 views
0

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

from functions import * 

powers = AutoVivification() 
powers[1] = {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1} 

print powers[1] 

мой autovivification является следующее (взято из: What is the best way to implement nested dictionaries?):

class AutoVivification(dict): 
    """Implementation of perl's autovivification feature.""" 
    def __getitem__(self, item): 
     try: 
      return dict.__getitem__(self, item) 
     except KeyError: 
      value = self[item] = type(self)() 
      return value 

печатает следующее:

{'A': 1, 'c1': 0.5, 'gamma': 1, 'lambda': 1} 

уведомление было изменено. теперь это в алфавитном порядке. есть ли способ предотвратить это? sory, не был достаточно ясен: (не меняя ключей и используя свойство autovivificaion «заставить произвольно расширять словарь супер легким»)

+6

Словари - это хэш-карты и не упорядочены. Если вам это нужно, вы можете использовать 'OrderedDict' из коллекций. – Hyperboreus

+0

Кроме того, ваш текущий класс 'AutoVivification' является, по существу, вложенным' defaultdict', как в 'dd = lambda: defaultdict (dd)' ... – l4mpi

+0

Все, что связано с авто-вивификацией, не имеет отношения к вопросу. Просто сделайте 'print {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}', и вы увидите значения, упорядоченные точно так же. – abarnert

ответ

3

Как the documentation говорит:

ключи и значения итерации в произвольном порядке, который не является случайным, различается по реализации Python, и зависит от истории словаря вставок и удалений.

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

>>> print {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1} 
{'A': 1, 'c1': 0.5, 'gamma': 1, 'lambda': 1} 

Если вы хотите Dict, который поддерживает свои ключи в порядке вставки, вы можете сделать это с OrderedDict.


Однако этого недостаточно, чтобы помочь вам в этом случае. Если вы строите dict (который имеет произвольный порядок), а затем передать, что к OrderedDict, все, что вы делаете замерзает, что начальный произвольный порядок:

>>> from collections import OrderedDict 
>>> print OrderedDict({'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}) 
OrderedDict([('A', 1), ('c1', 0.5), ('gamma', 1), ('lambda', 1)]) 

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

>>> print OrderedDict([('c1', 0.5), ('gamma', 1), ('lambda', 1), ('A', 1)]) 
OrderedDict([('c1', 0.5), ('gamma', 1), ('lambda', 1), ('A', 1)]) 

Если вы хотите автоматически оживлять OrderedDict, вы можете сделать это, используя OrderedDict вместо dict в существующем классе. Тем не менее, есть несколько проблем с классом, который вы используете, что вы, возможно, захотите рассмотреть. В частности, вы действительно хотите использовать super вместо вызовов классического стиля в методах родительского класса; если бы вы сделали это, вы могли бы просто определить class AutoVivifiedOrderedDict(OrderedDict, AutoVivification): pass и сделать это! Кроме того, я не думаю, что ваш класс будет правильно рассосаться как есть.


Если вы используете defaultdict для autovivification, он уже позаботился о всех сложных битов:

def AutoVivification(): 
    return defaultdict(AutoVivification) 

Если после этого вы хотите добавить заказ к этому, вы будете нуждаться в OrderedDefaultDict, так что вы может это сделать:

def OrderedAutoVivification(): 
    return OrderedDefaultDict(AutoVivification) 

Если вы не знаете, как создать OrderedDefaultDict себя, искать рецепты. (Вы можете почти просто наследовать от обоих классов ... за исключением того факта, что у них разные подписи, поэтому вам нужно подумать о том, как должен выглядеть ваш __init__ и явно вызвать правильные инициализаторы базы с правильными аргументами. См. this question для некоторых обсуждение.)

+0

попробовал это, все равно получить то же самое. изменил мой код на: 'powers = OrderedAutoVivification()', использовал ваш код: 'def OrderedAutoVivification(): return OrderedDefaultDict (AutoVivification)' и использовал 'OrderedDefaultDict' из [link] (http://stackoverflow.com/ вопросы/4126348/как-ду-я-переписывание-это функция в реализации-ordereddict/4127426 # 4127426). Я продолжу искать .. – juggler

+0

Возможно, я должен задать другой вопрос с новым кодом. гектометр Я заканчиваю это не просто .. (очевидно?) – juggler

+0

@juggler: Вы прочитали мой весь ответ? Я объяснил, почему вы получите то же самое: '{'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}' is 'dict', что означает, что он имеет произвольное заказ. Присвоение того, что произвольно упорядоченный 'dict' to' powers [1] 'будет просто блокироваться в этом оригинальном произвольном порядке в качестве постоянного порядка. Вы должны избегать построения 'dict' в первую очередь, используя последовательность пар (или добавляя значения один за другим или каким-то другим способом). – abarnert

-1

Словари не упорядочены в Python. Он не сохранит свой заказ после сортировки. Вместо этого используйте

from collections import OrderedDict 

powers = OrderedDict() 
powers[1] = {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1} 

print powers[1] 
+0

Ссылка на «сортируемый» здесь запутан; Я не уверен, что вы хотели сказать. – abarnert

+0

будет использовать метод OrderedDict() так же, как AutoVivification(), а также заказать его? (Я все еще неясен в автовивитации, все, что я действительно знаю, это то, что он делает произвольно расширяющий словарь супер легким, что отлично) – juggler

+0

@MichaelJensen: простой способ сделать автовивитацию - с 'defaultdict', как объясняет комментарий l4mpi. Если вы хотите, чтобы он был заказан _and_ auto-vivified, вы можете использовать 'OrderedDefaultDict' (искать рецепт для него, если вы не знаете, как его создать самостоятельно) точно так же. – abarnert

-4

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

import operator 

powers = {0: ['c1', 0.5], 1: ['gamma', 1], 2: ['lambda', 1], 3: ['A', 1]} 
print sorted(powers.items(), key=operator.itemgetter(0)) 

Надеется, что это помогает!

+0

Ответьте на неправильный вопрос? – Hyperboreus

+0

Как это?DropDownListValues ​​- это Dict. –

+0

1. Это о худшем способе заказа dict и 2. Этот вопрос не имеет ничего общего с jinja или html. – l4mpi

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

  • Нет связанных вопросов^_^