我有一个奇怪的问题。根据像this这样的帖子,我希望IDLE比在命令行上运行我的代码要慢。但是,我看到完全相反。
程序比较两个文件并将匹配的线对组合在一起,并将所有匹配项写入新文件。我认为它类似于SQL中的连接。但我需要忽略没有匹配的行。以下是该计划的概述:
当程序试图访问非常大的字典时似乎被卡住了。在IDLE中运行大约需要2-3分钟,但是在1小时后程序仍未在命令行上完成。当我访问write_file时,它写入它只是以非常慢的速度前进。
以下是第一个文件的一些简化数据,其中数据由制表符分隔,数字是键,值是信息:
20 \ tinfo_first_file_20 \ n
18 \ tinfo_first_file_18 \ n
以下是第二个文件的示例:
20 \ tinfo_second_file_20 \ n
30 \ tinfo_second_file_20 \ n
以下是正在编写的文件的示例:
20 \ tinfo_first_file_20 \ T20 \ tinfo_second_file_20 \ n
功能
def pairer(file_1, file_2, write_file):
wf = open(write_file, 'w')
f1 = open(file_1, 'r')
line = f1.readline()
d = {}
while line != "":
key, value = line.strip('\n').split('\t')
d[key] = value
line = f1.readline()
f2 = open(file_2, 'r')
line_2 = f2.readline()
while line_2 != "":
key, value = line_2.strip('\n').split('\t')
if key in d.keys():
to_write = key +'\t' + d[key] + '\t' + key +'\t'+ value + '\n'
wf.write(to_write)
line_2 = f2.readline()
我如何在IDLE中运行代码
if __name__=="__main__":
pairer('file/location/of/file_1', 'file/location/of/file_2', 'file/location/of/write_file')
我如何在终端中运行代码
if __name__=="__main__":
parser = argparse.ArgumentParser()
parser.add_argument('file_1', action="store")
parser.add_argument('file_2', action="store")
parser.add_argument('write_file', action="store")
results = parser.parse_args()
pairer(results.file_1, results.file_2, results.write_file)
所有代码都是对实际代码的简化。我希望我包含足够的内容,允许有人指出我正确的方向,但不要太多,所以我坚持到底。我是编程新手所以这可能是一个明显的问题,但我找不到任何东西。
使用终端时是否有字典的最大大小?它是以不同方式存储的,最终会最大化我的记忆吗?
我有Mac OSX 10.8。 Tkinter已更新。我正在使用python2.7。 提前致谢。
修改
在程序到达这一点之前,它确实有大约30分钟的其他分析要做。但它只在这里失败了。不确定这是否相关。另一部分只是将大型文件~30kb分成22个较小的文件。这里没有涉及字典,速度大致相同。所以我可以在较小的层面上处理数据。
编辑2:
使用终端时内存是否有明显区别?
我还注意到另一件事:当我查看Activity Monitor App时,当我在IDLE中运行代码时,它似乎使用了更多的CPU。我看起来它正在使用多个处理器,但这没有意义。由于我的代码不是并行编写的。当我在IDLE中运行时,计算机也会产生更多噪音。不是很量,而是观察。
答案 0 :(得分:0)
一个1kb的文件听起来很小,但这里有一些可能解决问题的提示,因为这个问题有点模糊:
使用argparse意味着在命令行中你需要像:
python prog.py --file_1 file --file_2 file --write_file output
我不确定这是不是你想要的。你可以保持简单,做一些事情:
if __name__ == '__main__':
file_1 = sys.argv[1]
file_2 = sys.argv[2]
write_file = sys.argv[3]
pairer(file_1, file_2, write_file)
您可以将其称为:
python prog.py file_1 file_2 write_file
另外,这主要是一个样式问题,但我会稍微修改一下pairer - 在文件上使用for循环,而不是创建keys()列表。
def pairer(file_1, file_2, write_file):
d = {}
# using 'with' prevents lost resources!
with open(file_1, 'r') as f1:
for line in f1:
# no arguments in strip clears all whitespace
key, value = line.strip().split('\t')
d[key] = value
f2 = open(file_2, 'r')
line_2 = f2.readline()
with open(file_2, 'r') as f2, open(write_file, 'w') as wf:
key, value = line_2.strip().split('\t')
# don't do 'if key in d.keys()' because .keys() constructs a list of keys
# the in operator checks the key directly, which is O(1) instead of O(n)
# this should give you a pretty big speed boost
if key in d:
# this is probably a trivial speed difference, but you could try it this way:
to_write = '\t'.join([key, d[key], key, value + '\n'])
wf.write(to_write)