我有一个 \ n 分隔字符串( strings.txt )的输入列表,我试图在输入中只将每一个匹配一次文件( infilelist.tsv ),并将每一行打印到一个新文件( outfile.tsv )。
我的outfile.tsv只有infilelist.tsv打印的次数与我搜索的输入字符串的次数相同,而不是一次。我的for(for(循环不正确地只是乘以infilelist.tsv文件而不是单个匹配的行?)有什么问题?
#!/usr/bin/python
# gets each line containing string input
inlist = []
with open('strings.txt','r') as inlist:
inlist = [line.strip() for line in inlist.readlines()]
tsvin = []
with open('infilelist.tsv','r') as tsvin:
tsvin = [line.strip() for line in tsvin.readlines()]
tsvout = []
for item in inlist:
for row in tsvin:
tsvout.append(row)
with open('outfile.tsv', 'w') as outobj:
outobj.writelines('\n'.join(map(str,tsvout)))
string1
string2
string3
string1\tabc123\tinfo
not_important
string2\tbcd234\tinformation
unimportant
string3\tcde345\tinformacion
less_than_important
string1\tabc123\tinfo
string2\tbcd234\tinformation
string3\tcde345\tinformacion
答案 0 :(得分:3)
for item in inlist:
for row in tsvin:
tsvout.append(row)
是双循环。 对于inlist
中的每个项目,这将遍历tsvin
中的每一行。
所以这不只是迭代tsvin
一次,它重复迭代len(inlist)
次。
相反,您可以通过tsvin
:
with open('strings.txt', 'rb') as inlist, open('infilelist.tsv', 'rb') as tsvin, open('outfile.tsv', 'wb') as outobj:
seen = set([line.strip() for line in inlist])
for line in tsvin:
if line.split('\t', 1)[0] in seen:
outobj.writelines(line)
请注意
seen = set([line.strip() for line in inlist])
正在inlist
中创建一组所有行。
line.split('\t', 1)[0] in seen
将标签tsvin
中的行最多拆分一次,并检查第一部分是否在集合seen
中。 Checking membership in a set is O(1)
,同时检查列表中的成员身份是O(n)
。因此,您可以通过seen
set
而不是list
来节省一些时间。