【问题标题】:string to OrderedDict conversion in pythonpython中的字符串到OrderedDict的转换
【发布时间】:2012-05-16 22:46:40
【问题描述】:

我通过导入集合创建了一个 python 有序字典并将其存储在一个名为“filename.txt”的文件中。文件内容看起来像

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

我需要从另一个程序中使用这个 OrderedDict。我这样做

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

我需要得到'mydict'的类型

<class 'collections.OrderedDict'>

但在这里,它的类型是“str”。
python中有什么方法可以将字符串类型转换为OrderedDict类型?使用 python 2.7

【问题讨论】:

  • 我对你的问题没有很好的答案(即不使用eval),但你真的不应该那样存储它。
  • 不要这样存储您的数据。至少使用泡菜。我会否决任何建议使用 eval() 的答案
  • 人们害怕eval的原因本质上是宗教而非理性。每种语言结构的存在都是有原因的,当一个 eval(x) 可以解决问题时,无需发明复杂的东西。是的,应该谨慎使用它(就像其他任何东西一样),但只要数据来自受信任的来源,使用eval 就可以了。
  • @thg435 好吧,由于我们不知道数据是否来自受信任的来源,因此迈出了一大步。即使是这样,当有很多更好的方法时,为什么还要使用丑陋、缓慢、潜在危险、难以调试的方法。这里真正的问题是数据是如何存储的,并且以另一种格式存储它还有其他优势(例如,如果您需要 Python 以外的数据怎么办?)。
  • @Lattyware:评估辩论已经厌倦了说最好的。就像几十年前的“goto”一样,人们似乎对它产生了某种非理性的恐惧。我们中的大多数人认为它本身就是邪恶的,并相信只写一次就会给他们的代码甚至他们的生活带来永恒的诅咒。这似乎是某种宗教,因此与计算机编程的理性世界无关。

标签: python string parsing ordereddictionary


【解决方案1】:

您可以使用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'>

【讨论】:

  • 请注意,泡菜可能和 eval 一样危险。不要解开您无法信任的数据
  • @gnibbler:+1 提到泡菜不安全。另请参阅:nadiana.com/python-pickle-insecure
【解决方案2】:

这里最好的解决方案是以不同的方式存储您的数据。以Encode it into JSON 为例。

您也可以使用the pickle module,如其他答案中所述,但这存在潜在的安全问题(如下面的eval() 所述) - 因此,如果您知道数据始终是可信的,请仅使用此解决方案。

如果不能改变数据的格式,那么还有其他的解决办法。

真正糟糕的解决方案是使用eval() 来执行此操作。这是一个真的 真的坏主意,因为它不安全,因为任何放入文件中的代码都将与other reasons

一起运行

更好的解决方案是手动解析文件。好处是有一种方法可以让你在这方面作弊并且更容易做到这一点。 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))

【讨论】:

  • +1,如果有两件事,那就是+2:a)可能,b)更清楚地表明“真正糟糕的解决方案”实际上是“纯粹的邪恶 "
  • 解决当前问题的好方法,我也在想同样的事情。
  • @Cpfohl, c) 如果 +2 是可能的
  • @gnibbler: 见a ;-)...哎呀...语法错误 1450 歧义解析
  • 有趣的是,link 上的 cmets 证明恰恰相反,即 eval 并没有错。
【解决方案3】:

这不是一个好的解决方案,但它确实有效。 :)

#######################################
# 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

【讨论】:

    【解决方案4】:

    这是我在 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
    

    同样,您可能应该以不同的方式编写文本文件。

    【讨论】:

      猜你喜欢
      • 2021-10-24
      • 2019-09-28
      • 2019-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 2015-09-02
      • 1970-01-01
      相关资源
      最近更新 更多