python - 使用循环创建命名元组实例作为数据库记录

标签 python numpy namedtuple

我想知道是否可以在循环内实例化命名元组。我遇到的问题是我有单独的文件(> 500),每个文件都应该是命名元组的实例,我想使用文件名来访问记录。 例如假设我有一个具有三个属性的命名元组

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_ids 是保存在列表中的文件名。 我希望 varname 作为文件名。因此,如果我的文件是 record1.txt,那么我可以在任何地方访问 record1.length。 我的问题是: 1)这是一个明智的做法吗?我需要对更大的数据集执行数学运算,这不是为了保存记录。 2)这可能吗?或者有更Pythonic的替代方案吗?

非常感谢您的建议!

最佳答案

分配给 varname 可能会给您带来问题,特别是因为它不会迭代,并且您最终会得到一个可引用的元组,而不是您希望能够查看的一大堆元组。

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

对于对象列表,对象不需要名称,因此不需要变量,只需集合列表类型就足够了。如果您知道记录 ID,则稍后迭代记录的代价是无法引用记录。用变量命名每个变量的情况会指数级恶化。

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

无论如何,对于记录的命名引用,字典都会用变量来标记。您的记录 ID 可以选择在类中,以防您将记录移动到列表并由于某种原因与字典键分离... 使用记录 id 作为字典键,以下内容大致近似于您最终得到的数据模型: dict_varname = {'record_id_unique': }

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

from collections import namedtuple as nt
reads = nt('reads', ('id', 'length', 'text'))

该原型(prototype)的某些项目可以重复使用,甚至在创建实例时也是如此。

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 将保留您不覆盖的值,为您首先赋予原型(prototype)的值创建一组灵活的默认值(类的声明/实例读取标记为“reads”)。

my_record_dict = {}
data = ['so_long', 'lots_of_data']
    for recordid in recordid_list:
        for data in recordid_datalist:
            my_record_dict[recordid] = reads('reads', length=len(data[0]), text=data[1])

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

如果到目前为止您一直遵循默认值,那么其余部分将“修复”上面的问题,即依赖于读取 ._replace 值并在循环中创建新实例,而不重复所有值。如上所示,您可以执行以下操作,但是如果您这样做,._replace 和语法的工作方式会很不稳定,即要求所有值。请参阅上文,了解“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)

我希望这会有所帮助。

关于python - 使用循环创建命名元组实例作为数据库记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51635713/

相关文章:

python - Typing.NamedTuple 和可变默认参数

python - 如何验证 namedtuple 值?

python - Windows 文件路径中的反斜杠?

python - numpy.random.seed 是否使结果固定在不同的计算机上?

python - 如何从终端输出 python 图形?

python - 获取数组中匹配元素的索引,考虑重复

python - 使用许多@properties 扩展 Python namedtuple?

python - 如何在 Python 中创建对数间隔数组?

python - 使用 super() 继承关键字参数,但只有在创建实例时指定时才会列出它们

Python TypeError : CommandEvent. GetString(): 参数太多