如何将两个文件中的行与python中的条件组合?

时间:2012-03-30 21:23:21

标签: python

我需要在两个文件中组合行,根据条件,其中一个文件的行是第二个文件行的一部分。

第一个文件的一部分:

12319000    -64,7357668067227   -0,1111052148685535  
12319000    -79,68527661064425  -0,13231739777754026  
12319000    -94,69642857142858  -0,15117839559513543    
12319000    -109,59301470588237 -0,18277783185642743  
12319001    99,70264355742297   0,48329515727315125  
12319001    84,61113445378152   0,4060446341409862  
12319001    69,7032037815126    0,29803063228455073  
12319001    54,93886554621849   0,20958105041136763  
12319001    39,937394957983194  0,13623056582981297  
12319001    25,05574229691877   0,07748669438398018  
12319001    9,99716386554622    0,028110643107892755  

第二个文件的一部分:

12319000.abf    mutant  1  
12319001.abf    mutant  2  
12319002.abf    mutant  3  

我需要创建一个文件,其中的行包含:第一个文件中的所有行和第二个文件中的所有行。除了第一列中的文件名。

正如您所看到的,第一个文件中有多行,而第二个中的行与另一行相对应。我需要对每一行进行操作,因此输出应该是这样的:

12319000    -94,69642857142858  -0,15117839559513543  mutant    1  
12319000    -109,59301470588237 -0,18277783185642743  mutant    1  
12319001    99,70264355742297   0,48329515727315125  mutant 2  
12319001    84,61113445378152   0,4060446341409862  mutant  2  

我写了这段代码:

oocytes = open(file_with_oocytes, 'r')  
results = open(os.path.join(path, 'results.csv'), 'r')  
results_new = open(os.path.join(path, 'results_with_oocytes.csv'), 'w')  
for line in results:  
    for lines in oocytes:  
        if lines[0:7] in line:  
            print line + lines[12:]  

但是它打印出来了,仅此而已,第一个文件中有45行:

12319000    99,4952380952381    0,3011778623990699
    mutant  1  

12319000    99,4952380952381    0,3011778623990699
    mutant  2  

12319000    99,4952380952381    0,3011778623990699
    mutant  3  

代码有什么问题? 或者它应该以某种方式完全不同?

3 个答案:

答案 0 :(得分:6)

Python中的文件句柄有状态;也就是说,它们不像列表那样工作。您可以重复遍历列表并每次都获取所有值。另一方面,文件具有下一个read()将发生的位置。迭代文件时,每行read()。到达最后一行时,文件指针位于文件的末尾。文件末尾的read()返回字符串''

您需要做的是在开始时在oocytes文件中读取一次,并存储值,可能是这样的:

oodict = {}
for line in oocytes:
    oodict[line[0:7]] = line[12:]

for line in results:
    results_key = line[0:7]
    if results_key in oodict:
        print oodict[results_key] + line

答案 1 :(得分:2)

请注意,此解决方案不依赖于任何字段的长度,除了第二个文件中文件扩展名的长度。

# make a dict keyed on the filename before the extension
# with the other two fields as its value
file2dict = dict((row[0][:-4], row[1:])  
                     for row in (line.split() for line in file2))

# then add to the end of each row 
# the values to it's first column
output = [row + file2dict[row[0]] for row in (line.split() for line in file1)]

仅出于测试目的,我使用了:

# I just use this to emulate a file object, as iterating over it yields lines
# just use file1 = open(whatever_the_filename_is_for_this_data)
# and the rest of the program is the same
file1 = """12319000    -64,7357668067227   -0,1111052148685535
12319000    -79,68527661064425  -0,13231739777754026
12319000    -94,69642857142858  -0,15117839559513543
12319000    -109,59301470588237 -0,18277783185642743
12319001    99,70264355742297   0,48329515727315125
12319001    84,61113445378152   0,4060446341409862
12319001    69,7032037815126    0,29803063228455073
12319001    54,93886554621849   0,20958105041136763
12319001    39,937394957983194  0,13623056582981297
12319001    25,05574229691877   0,07748669438398018
12319001    9,99716386554622    0,028110643107892755""".splitlines()

# again, use file2 = open(whatever_the_filename_is_for_this_data)
# and the rest of the program will work the same
file2 = """12319000.abf    mutant  1
12319001.abf    mutant  2
12319002.abf    mutant  3""".splitlines()

你应该只使用普通的文件对象。测试数据的输出是:

   [['12319000', '-64,7357668067227', '-0,1111052148685535', 'mutant', '1'],
    ['12319000', '-79,68527661064425', '-0,13231739777754026', 'mutant', '1'],
    ['12319000', '-94,69642857142858', '-0,15117839559513543', 'mutant', '1'],
    ['12319000', '-109,59301470588237', '-0,18277783185642743', 'mutant', '1'],
    ['12319001', '99,70264355742297', '0,48329515727315125', 'mutant', '2'],
    ['12319001', '84,61113445378152', '0,4060446341409862', 'mutant', '2'],
    ['12319001', '69,7032037815126', '0,29803063228455073', 'mutant', '2'],
    ['12319001', '54,93886554621849', '0,20958105041136763', 'mutant', '2'],
    ['12319001', '39,937394957983194', '0,13623056582981297', 'mutant', '2'],
    ['12319001', '25,05574229691877', '0,07748669438398018', 'mutant', '2'],
    ['12319001', '9,99716386554622', '0,028110643107892755', 'mutant', '2']]

答案 2 :(得分:1)

嗯,简单的事情首先,你在行尾打印换行符 - 你想要删除行[0:-1]

接下来,“lines [0:7]”只测试该行的前7个字符 - 你想测试8个字符。这就是为什么用3种不同的突变体值打印出相同的“线”值。

最后,您需要为结果中的每一行关闭并重新打开卵母细胞。如果不这样做,则在第一行结果后结束输出。

实际上,另一个答案更好 - 不要为每行结果打开和关闭卵母细胞 - 打开它并将其读入(列表中)一次,然后针对每行结果迭代该列表。