python - 用字符串填充字典

时间:2014-03-28 19:39:46

标签: python string dictionary

我有一个由多行组成的字符串,每行包含一个键和一个对象的2个属性的2个值。我想在字典中加载它们,字符串位于txt文件中。 我只能定义函数:

def load_a_string(self, thestring):

这是字符串在txt文件中的样子(我想要的字符串从第四行开始):

noir
False
None
((3, 0), 'blanc', 'pion')
((5, 4), 'blanc', 'pion')
((2, 1), 'noir', 'pion')
((2, 5), 'noir', 'pion')
((7, 2), 'blanc', 'pion')
((1, 2), 'noir', 'pion')
((6, 7), 'blanc', 'pion')
((7, 6), 'blanc', 'pion')
((6, 3), 'blanc', 'pion')
((5, 6), 'blanc', 'pion')
((5, 0), 'noir', 'pion')
((0, 1), 'noir', 'pion')
((3, 2), 'blanc', 'pion')
((2, 3), 'noir', 'pion')
((0, 7), 'noir', 'pion')
((1, 0), 'noir', 'pion')
((6, 5), 'blanc', 'pion')
((2, 7), 'noir', 'pion')
((7, 0), 'blanc', 'pion')
((6, 1), 'blanc', 'pion')
((7, 4), 'blanc', 'pion')
((0, 5), 'noir', 'pion')
((3, 4), 'noir', 'pion')

从第4行开始是我想要转换成dict的内容。每个数字元组都是dict中的一个键,另外两个是一个名为piece的类的实例(对象)的属性,' blanc'或者' noir'是属性piece.color和' pion'的值。是属性piece.thetype的值(它的其他可能值是' dame')。 基本上如果我想像上面那样手动填写字典,它就像这样:

self.cases = {}
self.cases[(3, 0)] = Piece("blanc", "pion")
self.cases[(5, 4)] = Piece("blanc", "pion")
self.cases[(2, 1)] = Piece("noir", "pion")
...

我正在制作的函数将一个字符串作为填充dict的参数。此函数用于另一个将读取上述txt文件的函数,并在文件中查找该字符串以将其用作此函数的参数。所以我也想知道如何在上面的txt文件中找到字符串,所以我可以将它传递给这个函数。最后一部分将在另一部分中。可能有一种更简单的方法可以做到这一点,但我真的需要这样做,所以一切都适合。

编辑:是的,这实际上是结构/格式,不幸的是我无法改变它。

5 个答案:

答案 0 :(得分:2)

如果这是真正的格式,最简单的方法是

rows = [x for x in open('file.ext', 'r')][3:]

for x in rows:
   key, color, thetype = eval(x)
   dict[key] = Piece(color, thetype)

答案 1 :(得分:1)

如果该文件是由Python生成的,并且您可以访问用于生成它的程序,或者可以诱导具有访问权限的人,则应考虑使用pickle模块来存储和保存Python的表示形式数据

如果您无法使用更可靠的存储机制,并且数据与示例中的数据完全相同,那么您可以为每一行执行类似的操作:

 line = line.translate(None, '()')
 terms = line.split(',')
 self.cases[(terms[0], terms[1]) = Piece(terms[2], terms[3])

答案 2 :(得分:0)

如果输入是安全的(它来自可信方),您可以使用eval,它接受带有Python代码的字符串,对其进行评估,然后返回结果。

例如:

from __future__ import print_function
from collections import namedtuple
from pprint import pprint
import sys

# Read the entire file to a list of lines
with open('my_text.txt', 'r') as f:
    lines = f.readlines()

# Declare a Piece class, which is a named tuple (immutable)
Piece = namedtuple('Piece', ['color', 'piece'])

# The cases dictionary where we will write
cases = {}

# For lines 4 to last, counting them starting at 4...
for num_line, line in enumerate(lines[3:], start=4):
    try:
        # Evaluate the line (will return a tuple)
        a_tuple = eval(line)

        # Separate the first element from the rest
        key, params = a_tuple[0], a_tuple[1:]

        # Write in the dictionary. *params is substituted with an argument for
        # each element in the tuple params.
        cases[key] = Piece(*params)
    except:
        # If something was wrong, print the line that failed in the text file
        # and raise the exception to get the traceback and stop the program.
        print("Failed to parse line %d: %s" % (num_line, line), file=sys.stderr)
        raise

# Pretty print the result
pprint(cases)

答案 3 :(得分:0)

纯Python字符串解决方案:

txt="""\
noir
False
None
((3, 0), 'blanc', 'pion')
((5, 4), 'blanc', 'pion')
((2, 1), 'noir', 'pion')
((2, 5), 'noir', 'pion')
((7, 2), 'blanc', 'pion')
((1, 2), 'noir', 'pion')
((6, 7), 'blanc', 'pion')
((7, 6), 'blanc', 'pion')
((6, 3), 'blanc', 'pion')
((5, 6), 'blanc', 'pion')
((5, 0), 'noir', 'pion')
((0, 1), 'noir', 'pion')
((3, 2), 'blanc', 'pion')
((2, 3), 'noir', 'pion')
((0, 7), 'noir', 'pion')
((1, 0), 'noir', 'pion')
((6, 5), 'blanc', 'pion')
((2, 7), 'noir', 'pion')
((7, 0), 'blanc', 'pion')
((6, 1), 'blanc', 'pion')
((7, 4), 'blanc', 'pion')
((0, 5), 'noir', 'pion')
((3, 4), 'noir', 'pion')"""

d={}
for line in txt.splitlines()[3:]:
    data=line.strip()[1:-1].split(',')
    d[line.partition(')')[0][1:]+')']=''.join(data[2:])

或者您可以使用来自ast的literal_eval

from ast import literal_eval

d={}
for line in txt.splitlines()[3:]:
    data=literal_eval(line)
    d[data[0]]=data[1:]

在任何一种情况下:

>>> d   
{(3, 0): ('blanc', 'pion'), (3, 2): ('blanc', 'pion'), (2, 1): ('noir', 'pion'), (2, 5): ('noir', 'pion'), (7, 2): ('blanc', 'pion'), (1, 2): ('noir', 'pion'), (6, 7): ('blanc', 'pion'), (7, 6): ('blanc', 'pion'), (6, 3): ('blanc', 'pion'), (5, 6): ('blanc', 'pion'), (5, 0): ('noir', 'pion'), (2, 7): ('noir', 'pion'), (5, 4): ('blanc', 'pion'), (2, 3): ('noir', 'pion'), (0, 7): ('noir', 'pion'), (1, 0): ('noir', 'pion'), (6, 5): ('blanc', 'pion'), (0, 1): ('noir', 'pion'), (7, 0): ('blanc', 'pion'), (6, 1): ('blanc', 'pion'), (7, 4): ('blanc', 'pion'), (0, 5): ('noir', 'pion'), (3, 4): ('noir', 'pion')}'blanc' 'pion'", '(1, 0)': " 'noir' 'pion'", '(1, 2)': " 'noir' 'pion'", '(6, 1)': " 'blanc' 'pion'", '(7, 0)': " 'blanc' 'pion'", '(2, 5)': " 'noir' 'pion'", '(5, 6)': " 'blanc' 'pion'", '(7, 6)': " 'blanc' 'pion'", '(5, 0)': " 'noir' 'pion'", '(7, 4)': " 'blanc' 'pion'", '(7, 2)': " 'blanc' 'pion'"}

答案 4 :(得分:0)

这是使用正则表达式提取数据的简单方法:

import re

f = open('data','r')
data = f.read()
f.close()

text = data.split('\n')
dict = {}
for line in text:
    key = re.findall(r"\((\(\d\,\s\d\)),", line)
    attr1 = re.findall(r",\s'(\w+)',", line)
    attr2 = re.findall(r",\s'(\w+)'\)", line)
    if len(key)>0:
        dict[key[0]] = (attr1[0], attr2[0])
print dict

这将处理文件内部行中数据的任何情况,并且只捕获所需的数据形式,并且您不必担心错误的格式化或空行,输出将是:

{'(3, 0)': ('blanc', 'pion'), '(3, 4)': ('noir', 'pion'), '(2, 7)': ('noir', 'pion'), '(2, 1)': ('noir', 'pion'), '(3, 2)': ('blanc', 'pion'), '(2, 3)': ('noir', 'pion'), '(0, 1)': ('noir', 'pion'), '(0, 7)': ('noir', 'pion'), '(0, 5)': ('noir', 'pion'), '(6, 3)': ('blanc', 'pion'), '(6, 5)': ('blanc', 'pion'), '(5, 4)': ('blanc', 'pion'), '(6, 7)': ('blanc', 'pion'), '(1, 0)': ('noir', 'pion'), '(1, 2)': ('noir', 'pion'), '(6, 1)': ('blanc', 'pion'), '(7, 0)': ('blanc', 'pion'), '(2, 5)': ('noir', 'pion'), '(5, 6)': ('blanc', 'pion'), '(7, 6)': ('blanc', 'pion'), '(5, 0)': ('noir', 'pion'), '(7, 4)': ('blanc', 'pion'), '(7, 2)': ('blanc', 'pion')}
希望这是一个帮助。