Python 使用循环将namedtuples的实例创建为数据库记录

Python 使用循环将namedtuples的实例创建为数据库记录,python,numpy,namedtuple,Python,Numpy,Namedtuple,我想知道是否有可能在循环中实例化namedtuples。我遇到的问题是,我有单个文件(>500),每个文件都应该是namedtuple的一个实例,我希望使用文件名来访问记录。 e、 g.假设我有一个具有三个属性的namedtuple from collections import namedtuple import pandas as pd record_ids=["record1","record2"] reads=namedtuple("reads", "id length text") f

我想知道是否有可能在循环中实例化namedtuples。我遇到的问题是,我有单个文件(>500),每个文件都应该是namedtuple的一个实例,我希望使用文件名来访问记录。 e、 g.假设我有一个具有三个属性的namedtuple

from collections import namedtuple
import pandas as pd
record_ids=["record1","record2"]
reads=namedtuple("reads", "id length text")
for record in record_ids:
    records=pd.read_table(record+".txt",dtype=None, header='infer')
    text=records.iloc[0:100]
    entry=[record,len(text),text)
    varname=reads._make(entry)
其中record_id是保存在列表中的文件名。 我希望varname是文件名。因此,如果我的文件是record1.txt,那么我可以在任何地方访问record1.length。 我的问题是: 1) 这是明智的做法吗?我需要在更大的数据集上执行数学运算,这不是为了保存记录。 2) 这可能吗?还是有更像蟒蛇的替代品


谢谢你的建议

分配给varname可能会使您遇到问题,尤其是因为它不会迭代,最终会得到一个可引用的元组,而不是您希望能够查看的大量元组列表

您可能需要考虑将每个Read()类实例化为对象集合。

对于对象列表,对象不需要名称,因此不需要变量,只需集合列表类型即可。如果您知道记录id,那么以后对记录进行迭代的代价是无法引用一个记录。使用变量命名每个记录会变得更糟

防止变量膨胀并能够通过记录id引用每个读取对象的解决方案是字典。这似乎与您的代码现在试图揭示元组的标识的方式一致,因为您稍后必须扫描以读取记录id,在您的情况下,记录id尚未变得唯一,因为您附加到它的所有内容都是“.txt”,并且您的id值似乎在列表中。该列表似乎可以从列表理解中获益

在任何情况下,对于记录的命名引用,字典都会标记一个变量。您的记录id可以选择在类中,以防由于某种原因将记录移动到列表并从字典键分离。。。 使用记录id作为字典键,以下内容大致与数据模型的最终结果相似: dict_varname={'record_id_unique':}

可以使用namedtuple.\u replace()方法重用原型namedtuple“reads”。原型永远不必进入列表,它只是作为功能蓝图可以访问。在您的示例中,它已经标记为变量“reads”。您可以将变量命名为不同的名称,但它是这样工作的。类名在namedtuple声明的括号内用引号括起来

from collections import namedtuple as nt
reads = nt('reads', ('id', 'length', 'text'))
该原型的某些项可以重用,甚至在创建实例时也是如此

my_record_list = []
for _ in range(len(list_of_records)):
    my_record_list.append(reads._replace(reads, id='record'+_, length=len(the_text), text=the_text))
._replace将保留您不覆盖的值,为您首先归属于原型的值(类的声明/实例读取标记为'reads')创建一组灵活的默认值

要读取数据,可以迭代键以提取对象(值)并从中读取所需的字段。您还可以更轻松地选择一条记录,而无需搜索所有记录来查找要查找的值的元组索引。字典键是不可变的,与遍历列表对象的索引相比,可以更快地找到这些散列值

如果到目前为止您已经遵循了默认值,那么下面的“修复”了上面的问题,也就是说,依赖于读取来替换值,并在循环中创建新实例,而不重复所有值。如上图所示,您可以执行以下操作,但如果执行,则语法会以一种不稳定的方式工作,即要求所有值。请参见上文,了解“reads”在新实例中是如何成为值的。狡猾,嗯

reads._replace(reads (id='123', length=999999, text='why?'))
最好创建一个实例,然后保存默认值,并从中创建新实例:

proto = reads('123', 999999, 'why not') # your default values on which to build
print(proto)
在标签下制作的最后一个示例。如果要使用循环中的替换值附加新实例,请删除标签:

k = proto._replace(id=34)
print(k)

我希望这会有所帮助。

这是一个小问题,但您也可以使用
reads(*entry)
entry
创建命名元组。创建命名可变的对象既不容易,也不受鼓励。通常我们会在列表或字典中收集
读取的
对象。@hpaulj感谢这两条评论!如果我将reads
reads
对象添加到列表/目录中,我仍然可以单独调用它们吗?与中一样,如果我使用
record
作为dict键,并且
对象读取为值,那么我仍然可以从特定对象访问单个字段(例如
text
)吗?再次感谢你
adict['record1']。text
应该可以用。@hpaulj太好了,非常感谢!
k = proto._replace(id=34)
print(k)