要列出的namedtuples的字符串

时间:2013-07-28 13:46:13

标签: python list sqlite type-conversion namedtuple

如何将namedtuples字符串转换为列表?

问题是我必须在SQLite的列中存储一个namedtuples列表,这显然不支持该格式。我想过把它转换成一个字符串。但是,由于我的元组是一个名字元组,我不知道如何从字符串再次列出。

>>> Point = namedtuple("Point", "x y", verbose = False)
>>> p = Point(3, 5)
>>> points = []
>>> points.append(Point(4, 7))
>>> points.append(Point(8, 9))
>>> points.append(p)
>>> p.x
3
>>> print points
[Point(x=4, y=7), Point(x=8, y=9), Point(x=3, y=5)]

我的命名元组列表是这样的^^^^,但它有6个参数而不是上面显示的2个参数。编辑 - 参数是布尔值,整数和字符串。

我尝试了映射,但是我收到了以下错误:

>>> string = str(points)
>>> l = string.strip("[]")
>>> p = map(Point._make, l.split(", "))

Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
p = map(Point._make, l.split(", "))
File "<string>", line 17, in _make
TypeError: Expected 2 arguments, got 9

我愿意采用其他更简单的方法来做到这一点。

3 个答案:

答案 0 :(得分:2)

我建议你使用像pickle这样的模块,允许在文件中存储python对象。

顺便说一句,我不确定namedtuple是否适用于pickle,如果是这种情况并且数据来源未知,那么您也可以eval使用repr 1}}:

repr上的帮助:

>>> print repr.__doc__
repr(object) -> string

Return the canonical string representation of the object.
For most object types, eval(repr(object)) == object.

示例:

>>> repr(points)
'[Point(x=4, y=7), Point(x=8, y=9), Point(x=3, y=5)]'
>>> eval(repr(points))
[Point(x=4, y=7), Point(x=8, y=9), Point(x=3, y=5)]

答案 1 :(得分:2)

最终,如何做到这一点可能是一个品味问题。

JSON

Json可以很好用,因为与pickle不同,它可以在python之外使用。您的对象是以广泛支持的,易于改变用途的格式序列化的。

>>> import json  # simple json is better bit I didn't want to force an install
>>> from collections import namedtuple
>>> Point = namedtuple("Point", "x y", verbose = False)
>>> p = Point(3,4)
>>> json.dumps(p._asdict())
'{"x": 3, "y": 4}'
>>> s = json.dumps(p._asdict())
>>> json.loads(s)  # not there yet cause thisis a dict
{u'y': 4, u'x': 3}   # but it is a dict that can create a Point
>>> Point(**json.loads(s))
Point(x=3, y=4)    

味酸

除非您定义属性状态,否则

pickle将无效(请参阅__getstate__ in the docs)。 从上面开始,这在加载阶段是“更好”:

import pickle

# Point.__getstate__=lambda self: self._asdict() # not needed as per @simon's comment thx simon
>>> pickle.dumps(p)
"ccopy_reg\n_reconstructor\np0\n(c__main__\nPoint\np1\nc__builtin__\ntuple\np2\n(I3\nI4\ntp3\ntp4\nRp5\nccollections\nOrderedDict\np6\n((lp7\n(lp8\nS'x'\np9\naI3\naa(lp10\nS'y'\np11\naI4\naatp12\nRp13\nb."
s = pickle.dumps(p)
>>> pickle.loads(s)
Point(x=3, y=4)

的eval

我会劝阻使用eval或exec。如果你沿着那条路走下去,请查看ast.literal_eval()并查看一些与SO相关的答案,例如safety of python eval

答案 2 :(得分:2)

根据Phil Cooper的回答,您可以以json格式存储对象:

>>> import json

>>> points_str = json.dumps([x._asdict() for x in points])
[{"x": 4, "y": 7}, {"x": 8, "y": 9}, {"x": 1, "y": 2}]

>>> points2 = [Point(**x) for x in json.loads(points_str)]
[Point(x=4, y=7), Point(x=8, y=9), Point(x=1, y=2)]

另一种奇怪的方法是使用exec

>>> points_str = repr(points)
'[Point(x=4, y=7), Point(x=8, y=9), Point(x=1, y=2)]'

>>> exec "points2 = %s" % points
>>> points2
[Point(x=4, y=7), Point(x=8, y=9), Point(x=1, y=2)]