【问题标题】:Python: Force heapq.merge to interpert strings as integers during comparisonPython:强制 heapq.merge 在比较期间将字符串解释为整数
【发布时间】:2015-07-20 15:11:31
【问题描述】:

我正在尝试合并一组预先排序的文件,其中每个文件中的每一行都是一个整数:

for line in heapq.merge(*files):

排序成功完成,但比较文件内容为字符串,而不是整数。如何强制进行整数比较?

【问题讨论】:

  • 无法在内存中存储文件,需要即时读取大文件。

标签: python sorting casting merge


【解决方案1】:

试试这个:

for line in heapq.merge(*(map(int, file) for file in files)):

这不会在比较过程中将字符串解释为整数,而是在运行时将它们更改为整数。因此,结果是整数,而不是字符串。如果需要,当然可以转换回字符串:

for line in map(str, heapq.merge(*(map(int, file) for file in files))):

供其他人/未来参考:这适用于 Python 3,其中map 返回一个迭代器。在 Python 2 中,map 需要替换为 itertools.imap,以便在启动时不会将所有内容读入内存。

【讨论】:

  • @RedLeader 确定一下:您使用的是 Python 3,对吧?
  • @RedLeader 好的 :-) 在 Python 2 中它必须是 itertools.imap 而不是 map。
  • @RedLeader 感谢您指出 heapq.merge,顺便说一句。我不知道这是一个正常的合并,我以为它只会将堆合并到一个堆中(不一定是完全排序的)。
【解决方案2】:

尝试读取文件并将每一行转换为整数。这假设所有数据都适合内存。

def read_as_int_list(file_name):
    with open(file_name) as fobj:
        return [int(line) for line in fobj]

这应该更节省内存:

def read_as_ints(file_name):
    with open(file_name) as fobj:
        for line in fobj:
            yield int(line)

用法:

files = (read_as_ints(name) for name in list_of_file_names)
for line in heapq.merge(*files):
    print(line)

【讨论】:

  • 应该加上那个条件。无法将值存储在内存中,这就是为什么我尝试使用此实现来动态读取每个输入流的顶部。
  • @RedLeader 添加了一个可以处理大文件的版本。让我知道它是否适合您。
猜你喜欢
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-05
  • 1970-01-01
  • 2011-06-21
  • 2012-02-09
  • 1970-01-01
相关资源
最近更新 更多