Python 输出具有特定列的特定初始字符串的行

Python 输出具有特定列的特定初始字符串的行,python,tab-delimited-text,Python,Tab Delimited Text,我有一个以制表符分隔的txt文件,如下所示: A B aaaKP C D bbbZ E F cccLL 这是以制表符分隔的 如果 然后我只想要那些第三列以aaa或bbb开头的行 输出将是 A B aaaKP C D bbbZ 对于只有一个短语的情况,我有一个代码 phrase, column = 'aaa', 3 fn = lambda l : len(l) >= column and len(l[column-1]) >= len(phr

我有一个以制表符分隔的txt文件,如下所示:

A   B   aaaKP
C   D   bbbZ
E   F   cccLL
这是以制表符分隔的

如果

然后我只想要那些第三列以aaa或bbb开头的行

输出将是

A   B   aaaKP
C   D   bbbZ
对于只有一个短语的情况,我有一个代码

phrase, column = 'aaa', 3
fn = lambda l : len(l) >= column and len(l[column-1]) >= len(phrase) and phrase == l[column-1][:len(phrase)]
fp = open('output.txt', 'w')
fp.write(''.join(row for row in open('input.txt') if fn(row.split('\t'))))
fp.close()
但是如果有多个短语。。我试过了

phrase, column = {'aaa','bbb'}, 3

但它不起作用。

解决方案:

#!/usr/bin/env python


import csv
from pprint import pprint


def read_phrases(filename, phrases):
    with open(filename, "r") as fd:
        reader = csv.reader(fd, delimiter="\t")
        for row in reader:
            if any((row[2].startswith(phrase) for phrase in phrases)):
                yield row


pprint(list(read_phrases("foo.txt", ["aaa"])))
pprint(list(read_phrases("foo.txt", ["aaa", "bbb"])))
$ python foo.py
[['A', 'B', 'aaaKP']]
[['A', 'B', 'aaaKP'], ['C', 'D', 'bbbZ']]
示例:

#!/usr/bin/env python


import csv
from pprint import pprint


def read_phrases(filename, phrases):
    with open(filename, "r") as fd:
        reader = csv.reader(fd, delimiter="\t")
        for row in reader:
            if any((row[2].startswith(phrase) for phrase in phrases)):
                yield row


pprint(list(read_phrases("foo.txt", ["aaa"])))
pprint(list(read_phrases("foo.txt", ["aaa", "bbb"])))
$ python foo.py
[['A', 'B', 'aaaKP']]
[['A', 'B', 'aaaKP'], ['C', 'D', 'bbbZ']]

您可以使用python的re模块来实现这一点

>>> import re
>>> data = """A   B   aaaKP
... C   D   bbbZ
... E   F   cccLL"""
>>> m = re.findall(r'^(?=\S+\s+\S+\s+(?:aaa|bbb)).*$', data, re.M)
>>> for i in m:
...     print i
... 
A   B   aaaKP
C   D   bbbZ
正向前瞻用于检查行是否包含特定字符串。上面的正则表达式检查第三列以
aaa
bbb
开头的行。如果是,则将打印相应的行

你也可以试试这个正则表达式代码

>>> s = """A    B       aaaKP
... C   D       bbbZ
... E   F       cccLL
... """
>>> m = re.findall(r'^(?=\S+\t\S+\t(?:aaa|bbb)).*$', s, re.M)
>>> for i in m:
...     print i
... 
A   B   aaaKP
C   D   bbbZ

一般情况下,您可以使用带有分支的正则表达式进行快速匹配和搜索:

import re

phrases = [ 'aaa', 'bbb' ]
column = 3

pattern = re.compile('|'.join(re.escape(i) for i in phrases))
column -= 1

with open('input.txt') as inf, open('output.txt', 'w') as outf:
    for line in inf:
        row = line.split('\t')
        if pattern.match(row[column]):
            outf.write(line)
代码从所有可能的短语构建正则表达式,使用
re.escape
对特殊字符进行转义。本例中的结果表达式是
aaa | bbb
pattern.match
根据模式匹配字符串的开头(匹配必须从第一个字符开始)

但是,如果必须只将字符串开头与固定短语匹配,请注意接受元组,这是最快的代码:

 phrases = [ 'aaa', 'bbb' ]
 column = 3

 phrase_tuple = tuple(phrases)
 column -= 1

 with open('input.txt') as inf, open('output.txt', 'w') as outf:
     for line in inf:
         row = line.split('\t')
         if row[column].startswith(phrase_tuple):
             outf.write(line)

它还演示了如何使用上下文管理器打开文件,在
output.txt
之前打开
input.txt
,这样,如果前者不存在,就不会创建后者。最后显示,没有任何发电机和lambda,这看起来最棒。

@Avinash_Raj谢谢!但这似乎并不像在output.txt中那样导入input.txt,然后保存输出。为此,该如何编辑?@Antti_Haapala谢谢!第一种方法有效。但是,第二种方法会产生一条错误消息“list object没有属性startswith”,已修复,
->
行[列]
忘记更改代码。@Anti_Haapala非常感谢!:)