这是一个问题,但是我也只是希望我不必编写一堆代码即可获得想要的行为。 (此外,如果它已经存在,它的运行速度可能比我写的还要快。)我有很多无法容纳在内存中的大型数字列表-至少不是同时所有。很好,因为一次只需要每个列表的一小部分,而且我知道如何将列表保存到文件中并读出所需的部分列表。问题是我执行此操作的方法效率不高,因为它涉及遍历文件中所需的部分。因此,我想知道是否有某个库或某个我找不到的库使我可以使用我熟悉的[]
标记来索引文件,就好像它是一个列表一样。由于我自己编写文件,因此我可以根据需要进行格式化,但是目前我的文件只包含列表元素,其中\n
是值之间的分隔符。
只是总结一下我要寻找的内容/使其更具体。
f[1:3]
)应作为内存中的python列表对象返回f[i] = x
应该在对应于索引{{1}的位置将值x
写到文件f
})说实话,我不希望这种情况存在,但您永远不知道何时错过您的研究。所以,我想问一下。附带说明一下,如果不存在,是否可以在python中重载i
运算符?
答案 0 :(得分:1)
如果数据是纯数字的,则可以考虑使用numpy
数组,并以npy
格式存储数据。以这种格式存储后,您可以将内存映射文件加载为:
>>> X = np.load("some-file.npy", mmap_mode="r")
>>> X[1000:1003]
memmap([4, 5, 6])
此访问将直接从磁盘加载,而无需加载前导数据。
答案 1 :(得分:1)
实际上,您可以通过编写一个简单的类来做到这一点:
class FileWrapper:
def __init__(self, path, **kwargs):
self._file = open(path, 'r+', **kwargs)
def _do_single(self, where, s=None):
if where >= 0:
self._seek(where)
else:
self._seek(where, 2)
if s is None:
return self._read(1)
else:
return self._write(s)
def _do_slice_contiguous(self, start, end, s=None):
if start is None:
start = 0
if end is None:
end = -1
self._seek(start)
if s is None:
return self._read(end - start)
else:
return self._write(s)
def _do_slice(self, where, s=None):
if s is None:
result = []
for index in where:
file._seek(index)
result.append(file.read(1))
return result
else:
for index, char in zip(where, s):
file._seek(index)
file._write(char)
return len(s)
def __getitem__(self, key):
if isinstance(key, int):
return self._do_single(key)
elif isinstance(key, slice):
if self._is_contiguous(key):
return self._do_slice_contiguous(key.start, key.stop)
else:
return self._do_slice(self._process_slice(key))
else:
raise ValueError('File indices must be ints or slices.')
def __setitem__(self, key, value):
if isinstance(key, int):
return self._do_single(key, value)
elif isinstance(key, slice):
if self._is_contiguous(key):
return self._do_slice_contiguous(key.start, key.stop, value)
else:
where = self._process_slice(key)
if len(where) == len(value):
return self._do_slice(where, value)
else:
raise ValueError('Length of slice not equal to length of string to be written.')
def __del__(self):
self._file.close()
def _is_contiguous(self, key):
return key.step is None or key.step == 1
def _process_slice(self, key):
return range(key.start, key.stop, key.step)
def _read(self, size):
return self._file.read(size)
def _seek(self, offset, whence=0):
return self._file.seek(offset, whence)
def _write(self, s):
return self._file.write(s)
自从我匆忙完成这项工作以来,我确定可以做出很多优化,但是写起来很有趣。
这不能完全回答问题,因为它支持对字符的随机访问,就像对行的假定那样,行的抽象性更高,处理起来也更复杂(因为它们可以可变长度)