-1

我有 2 个文本文件,“animals.txt”和“colors.txt”,如下所示,其中每行中的 2 个字符串由制表符分隔。

“动物.txt”

12345  dog

23456  sheep

34567  pig

“颜色.txt”

34567  pink

12345  black

23456  white

我想编写 Python 代码:

  1. 对于“animals.txt”中的每一行,第一列中的字符串(12345,然后是 23456,然后是 34567)
  2. 将此字符串与“colors.txt”中第一列中的字符串进行比较
  3. 如果找到匹配项 (12345 == 12345, etc) ,它会写入两个输出文件:

output1,包含animals.txt的行+colors.txt第二列对应查询值(12345)的值:

12345 dog   black
23456 sheep white
34567 pig   pink 

output2 包含 colors.txt 的第二列中与查询值相对应的值列表(12345,然后是 23456,然后是 34567)):

black
white
pink
4

4 回答 4

5

如果顺序无关紧要,这将成为一个非常简单的问题:

with open('animals.txt') as f1, open('colors.txt') as f2:
    animals = {} 
    for line in f1:
        animal_id, animal_type = line.split('\t')
        animals[animal_id] = animal_type

    #animals = dict(map(str.split,f1)) would work instead of the above loop if there are no multi-word entries.

    colors={}
    for line in f2:
        color_id, color_name = line.split('\t')
        colors[color_id] = color_name

    #colors = dict(map(str.split,f2)) would work instead of the above loop if there are no multi-word entries.
    #Thanks @Sven for pointing this out.

common=set(animals.keys()) & set(colors.keys())  #set intersection. 
with open('output1.txt','w') as f1, open('output2.txt','w') as f2:
     for i in common:  #sorted(common,key=int) #would work here to sort.
         f1.write("%s\t%s\t%s\n"%(i,animals[i],colors[i])
         f2.write("%s"%colors[i])

您可以通过defaultdict在遇到特定键时附加到列表的方式更优雅地执行此操作,然后在编写时测试列表的长度是否为 2,然后再输出,但是,我不相信这种方法更好。

于 2012-07-17T17:21:39.503 回答
3

你需要使用python吗?如果您使用的是 bash 并且您的输入未排序,请执行以下操作:

$ join -t $'\t' <( sort animals.txt ) <( sort colors.txt ) > output1
$ cut -f 3 output1 > output2

如果您没有支持进程替换的 shell,请对输入文件进行排序并执行以下操作:

$ join -t '<tab>' animals.txt colors.txt > output1
$ cut -f 3 output1 > output2

<tab>实际制表符在哪里。根据您的 shell,您可以使用 ctrl-V 后跟 tab 键来输入它。(或使用不同的分隔符进行剪切。)

于 2012-07-17T17:03:23.960 回答
1

我会用熊猫

animals, colors = read_table('animals.txt', index_col=0), read_table('colors.txt', index_col=0)
df = animals.join(colors)

结果是:

animals.join(colors)
Out[73]: 
       animal  color
id
12345  dog     black
23456  sheep   white
34567  pig     pink

然后按 id 的顺序输出颜色到文件:

df.color.to_csv(r'out.csv', index=False)

如果您无法将列标题添加到文本文件,则可以在导入时添加它们

animals = read_table('animals.txt', index_col=0, names=['id','animal'])
于 2012-07-23T02:04:26.390 回答
0

假设输入文件中的每一行的结构与示例完全相同:

with open("c:\\python27\\output1.txt","w") as out1, \ 
     open("c:\\python27\\output2.txt","w") as out2:

    for outline in [animal[0]+"\t"+animal[1]+"\t"+color[1] \
                    for animal in [line.strip('\n').split("\t") \
                    for line in open("c:\\python27\\animals.txt","r").readlines()] \
                    for color in [line.strip('\n').split("\t") \
                    for line in open("c:\\python27\\colors.txt","r").readlines()] \
                    if animal[0] == color[0]]:

        out1.write(outline+'\n')
        out2.write(outline[outline.rfind('\t')+1:]+'\n')

我想那会为你做的。

也许不是最优雅/快速/清晰的方法 - 但很短。我相信,从技术上讲,这是 4 行。

于 2012-07-17T18:08:37.507 回答