преобразование строки в OrderedDict в python

я создал упорядоченный словарь python, импортировав коллекции и сохранив его в файле с именем «filename.txt». содержимое файла выглядит так

OrderedDict([(7, 0), (6, 1), (5, 2), (4, 3)])

мне нужно использовать этот OrderedDict из другой программы. я делаю это как

myfile = open('filename.txt','r')
mydict = myfile.read()

мне нужно получить 'mydict' от Type

<class 'collections.OrderedDict'>

но здесь он имеет тип 'str'.
Есть ли в python способ преобразовать строковый тип в тип OrderedDict? используя питон 2.7


person srek    schedule 08.05.2012    source источник
comment
У меня нет хорошего ответа (т.е. не использовать eval) на ваш вопрос, но вам действительно не следует хранить его таким образом.   -  person jamylak    schedule 08.05.2012
comment
Не храните свои данные так. По крайней мере, используйте рассол. Я буду отрицать любые ответы, которые предлагают использовать eval()   -  person John La Rooy    schedule 08.05.2012
comment
Причины, по которым люди боятся eval, скорее религиозны, чем рациональны. Каждая языковая конструкция существует по какой-то причине, и нет необходимости изобретать что-то сложное, когда одна-единственная eval(x) делает свое дело. Да, его следует использовать с осторожностью (как и любую другую вещь), но пока данные поступают из надежного источника, использование eval вполне нормально.   -  person georg    schedule 08.05.2012
comment
@ thg435 Что ж, поскольку мы не знаем, получены ли данные из надежного источника, это большой шаг. Даже если это так, зачем использовать уродливый, медленный, потенциально опасный, сложный для отладки метод, когда есть множество лучших методов. Настоящая проблема здесь заключается в том, как хранятся данные, и хранение их в другом формате имеет другие преимущества (например, что, если вам нужны данные в чем-то другом, кроме Python?).   -  person Gareth Latty    schedule 09.05.2012
comment
@Lattyware: оценочные дебаты устали, если не сказать лучшего. Как и в случае с гото несколько десятилетий назад, у людей, кажется, развивается какой-то иррациональный страх перед ним. Большинство из нас считают это злом как таковым и верят, что всего лишь один раз написав его, они наложат вечное проклятие на свой код и даже на свою жизнь. Похоже, что это какая-то религия, и как таковая не имеет отношения к рациональному миру компьютерного программирования.   -  person georg    schedule 09.05.2012
comment
@ thg435 И, как и в случае с goto, это не то, что вам когда-либо нужно использовать в таком современном языке, как Python. Он там, потому что есть варианты использования и для вашей 2-минутной программы, чтобы сделать x, y или z - кого это волнует, но помимо этого, он всегда должен сопровождаться предупреждениями о вреде для здоровья.   -  person Gareth Latty    schedule 09.05.2012
comment
@Lattyware: просто из интереса попробуйте найти eval в папке python. Для меня find "/System/Library/Frameworks/Python.framework" -name "*.py" | xargs grep "eval(" | wc -l печатает 1212, так что да, у него есть применение. Что касается goto и современных языков, вам может быть интересно прочитать это классическое обсуждение.   -  person georg    schedule 09.05.2012
comment
@ thg435 Да, и это пример того, как вы можете разумно использовать goto, но с ним намного проще делать плохие вещи, так зачем беспокоиться, когда есть лучшие способы сделать что-то? У меня такой же мыслительный процесс с eval() - я всегда могу сделать это по-другому, и мне еще предстоит найти случай, когда в целом было бы более разумно использовать eval() вместо альтернативы. Всегда есть слишком много причин, чтобы сделать это по-другому.   -  person Gareth Latty    schedule 09.05.2012


Ответы (4)


Вы можете сохранить и загрузить его с помощью pickle.

import cPickle as pickle

# store:
with open("filename.pickle", "w") as fp:
    pickle.dump(ordered_dict, fp)

# read:
with open("filename.pickle") as fp:
    ordered_dict = pickle.load(fp)

type(ordered_dict) # <class 'collections.OrderedDict'>
person wong2    schedule 08.05.2012
comment
обратите внимание, что соленья могут быть такими же опасными, как и eval. Не разбирайте данные, которым вы не можете доверять - person John La Rooy; 08.05.2012
comment
@gnibbler: +1 за упоминание о том, что рассол небезопасен. См. также: nadiana.com/python-pickle-insecure - person rubik; 08.05.2012

Лучшее решение здесь — хранить данные по-другому. Закодируйте его в JSON, для пример.

Вы также можете использовать модуль pickle, как описано в других ответах, но это потенциально безопасно проблемы (как описано в разделе eval() ниже) — поэтому используйте это решение только в том случае, если вы знаете, что данным всегда можно доверять.

Если вы не можете изменить формат данных, то есть другие решения.

Действительно плохое решение — использовать для этого eval(). Это действительно действительно плохая идея, поскольку она небезопасна, поскольку любой код, помещенный в файл, будет выполняться вместе с другие причины

Лучшее решение - вручную проанализировать файл. Положительным моментом является то, что есть способ обмануть это и сделать это немного проще. В Python есть ast.literal_eval(), что позволяет легко анализировать литералы. Хотя это не литерал, поскольку он использует OrderedDict, мы можем извлечь литерал списка и проанализировать его.

Например: (не проверено)

import re
import ast
import collections

with open(filename.txt) as file:
    line = next(file)
    values = re.search(r"OrderedDict\((.*)\)", line).group(1)
    mydict = collections.OrderedDict(ast.literal_eval(values))
person Gareth Latty    schedule 08.05.2012
comment
+1, было бы +2, если бы было две вещи: а) возможно и б) более четко обозначено, что действительно плохое решение на самом деле чистое зло - person Chris Pfohl; 08.05.2012
comment
Хорошее решение текущей проблемы, я думал о том же. - person jamylak; 08.05.2012
comment
@Cpfohl, c) если бы +2 было возможно - person John La Rooy; 08.05.2012
comment
@gnibbler: см. a ;-)... Упс... СИНТАКСИЧЕСКАЯ ОШИБКА 1450 НЕОДНОЗНАЧНЫЙ АНАЛИЗ - person Chris Pfohl; 08.05.2012
comment
Интересно, что комментарии к вашей ссылке доказывают как раз обратное, а именно, в eval нет ничего плохого. - person georg; 08.05.2012
comment
@ thg435 В eval нет ничего плохого - это ужасный способ добиться цели, и есть гораздо лучшие способы сделать это, и в своем ответе я дал два хороших способа. В комментариях просто указано, что eval не уничтожит мир, они не доказывают его безопасность или хорошее решение подобной проблемы. - person Gareth Latty; 08.05.2012
comment
@Lattyware: ваше решение хорошее, за исключением того, что оно имеет длину более 200 байт, а x=eval(x) всего 9. - person georg; 08.05.2012
comment
@ thg435 Ну, это зависит от решения. Кодирование и декодирование в виде JSON (лучший способ) будет короче, но, несмотря на это, суть в том, что краткость — это не самое главное. - person Gareth Latty; 09.05.2012
comment
Это должен быть принятый ответ, потому что, хотя травление или изменение на какой-либо другой вывод было бы лучше, во многих случаях кто-то может не иметь доступа/разрешения на изменение источника или просто не может/не хочет снова запускать код (если это какой-то долгий процесс или входные данные исчезли), и это дает более одного решения вопроса ОП как есть - person physincubus; 15.03.2019

Это не очень хорошее решение, но оно работает. :)

#######################################
# String_To_OrderedDict
# Convert String to OrderedDict
# Example String
#    txt = "OrderedDict([('width', '600'), ('height', '100'), ('left', '1250'), ('top', '980'), ('starttime', '4000'), ('stoptime', '8000'), ('startani', 'random'), ('zindex', '995'), ('type', 'text'), ('title', '#WXR#@TU@@Izmir@@brief_txt@'), ('backgroundcolor', 'N'), ('borderstyle', 'solid'), ('bordercolor', 'N'), ('fontsize', '35'), ('fontfamily', 'Ubuntu Mono'), ('textalign', 'right'), ('color', '#c99a16')])"
#######################################
def string_to_ordereddict(txt):

    from collections import OrderedDict
    import re

    tempDict = OrderedDict()

    od_start = "OrderedDict([";
    od_end = '])';

    first_index = txt.find(od_start)
    last_index = txt.rfind(od_end)

    new_txt = txt[first_index+len(od_start):last_index]

    pattern = r"(\(\'\S+\'\,\ \'\S+\'\))"
    all_variables = re.findall(pattern, new_txt)

    for str_variable in all_variables:
        data = str_variable.split("', '")
        key = data[0].replace("('", "")
        value = data[1].replace("')", "")
        #print "key : %s" % (key)
        #print "value : %s" % (value)
        tempDict[key] = value

    #print tempDict
    #print tempDict['title']

    return tempDict
person Guray Celik    schedule 27.11.2014

Вот как я это сделал на Python 2.7

from collections import OrderedDict
from ast import literal_eval

# Read in string from text file
myfile = open('filename.txt','r')
file_str = myfile.read()

# Remove ordered dict syntax from string by indexing
file_str=file_str[13:]
file_str=file_str[:-2]

# convert string to list
file_list=literal_eval(file_str)

header=OrderedDict()
for entry in file_list:
    # Extract key and value from each tuple
    key, value=entry
    # Create entry in OrderedDict
    header[key]=value

Опять же, вам, вероятно, следует написать свой текстовый файл по-другому.

person oogieoogieful    schedule 23.08.2016