阅读 files/website 就好像它是 STDIN 一样不写代码两次

read files/website as if it's STDIN to not write code twice

对于 hackerRank,我经常发现自己编写的代码将输入作为 STDIN,但随后我想测试它的大输入,如从 file/site 获取输入。理想情况下,从文件读取而不是从 STDIN 读取时,我不必编写新代码。

即文件输入的一个例子是here:

但是 hackerRank 将输入作为 STDIN:

# Enter your code here. Read input from STDIN. Print output to STDOUT
N, l = map(int, raw_input().split())
# N, l = 100000, 2

pairs = []

for i in xrange(l):
    a, b = map(int, raw_input().split())
    # Store a and b in an appropriate data structure
    pairs.append((a, b))
# pairs = [(1,2), (3,4)]

是否有通用的方法来确保从文件读取时也与从 STDIN 代码读取兼容?

是的,重用代码肯定好。

这是一种方法。您可以创建一个 "acts like" raw_input 的对象,但是在调用时, 它从文件中读取而不是提示。

def go(fn_get_input):
    N, l = map(int, fn_get_input().split())
    # N, l = 100000, 2
    pairs = []
    for i in xrange(l):
        a, b = map(int, fn_get_input().split())
        # Store a and b in an appropriate data structure
        pairs.append((a, b))
    # pairs = [(1,2), (3,4)]

class GetInputFromFile(object):
    def __init__(self, filename):
        f = open(filename, 'r')
        self.lines = list(f)
        self.index = 0
        f.close()

    def __call__(self):
        ret = self.lines[self.index]
        ret = ret.rstrip() # remove the trailing newline
        self.index += 1
        return ret

# with raw input:
go(raw_input)
# with a file
go(GetInputFromFile('/path/to/file.txt'))

写测试也有这个很好。

同样的模式可用于通过 urllib2 从网站读取数据。请注意,在此代码示例中,如果调用该对象的次数超过文件中的行数,它将引发异常。

我是 fileinput 模块的忠实粉丝。来自 https://docs.python.org/3.5/library/fileinput.html :

The typical use is:

import fileinput
for line in fileinput.input():
    process(line)

This iterates over the lines of all files listed in sys.argv[1:], defaulting to sys.stdin if the list is empty. If a filename is '-', it is also replaced by sys.stdin.