过滤txt文件是否满足python中的某些条件?
我有一个txt文件,其中包含subjectid_num_u[dog/cat][option] 我想过滤文件以获得满足条件的输出。例如,下面的代码将文件化,输出的名称中包含过滤txt文件是否满足python中的某些条件?,python,python-3.x,Python,Python 3.x,我有一个txt文件,其中包含subjectid_num_u[dog/cat][option] 我想过滤文件以获得满足条件的输出。例如,下面的代码将文件化,输出的名称中包含CAT和GOOD,和不包含狗和GOOD。名称由相同的主题id和相同的编号num确定。但是,代码没有显示我的预期输出。我该怎么修 这是我的密码 with open("./cat_dog.txt", 'r') as f: files_list = [line.rstrip('\n') for line in f] file_
CAT
和GOOD
,和不包含狗
和GOOD
。名称由相同的主题id
和相同的编号num
确定。但是,代码没有显示我的预期输出。我该怎么修
这是我的密码
with open("./cat_dog.txt", 'r') as f:
files_list = [line.rstrip('\n') for line in f]
file_filter = []
for i, cat in enumerate(files_list):
if 'GOOD' in cat and 'CAT' in cat:
subject_id = cat.split('_')[0]
num_id = cat.split('_')[1]
subject_num = subject_id + '_' + num_id
for j, dog in enumerate(files_list):
if subject_num in dog and 'GOOD' in dog:
if 'GOOD' in dog and 'DOG' in dog:
continue;
else:
file_filter.append(cat)
电流输出为
ID1_0123_CAT_ANIMAL_GOOD_3
ID2_1234_CAT_ANIMAL_GOOD_3
而预期的是
ID1_0123_CAT_ANIMAL_GOOD_3
你的代码错了。考虑当你检查行<代码> ID2Y121234 CATAIMALALYGODYO3内循环:
subject_id = cat.split('_')[0] #ID2
num_id = cat.split('_')[1] # 1234
subject_num = subject_id + '_' + num_id #ID2_1234
for j, dog in enumerate(files_list):
# when dog is the line ID2_1234_CAT_ANIMAL_GOOD_3
if subject_num in dog and 'GOOD' in dog: # this is true
if 'GOOD' in dog and 'DOG' in dog: # this is false
continue;
else:
file_filter.append(cat) # then it outputs it
问题在于,每一行的GOOD
和CAT
都会在内部循环中“匹配自身”
我想我该怎么用itertools.groupby
。大致如下:
from itertools import groupby
def key(line):
return line.split('_')[:2]
for key, lines in groupby(sorted(files_list, key=key), key=key):
good_lines = [line for line in lines if 'GOOD' in line]
if len(good_lines) == 1 and 'CAT' in good_lines[0]:
file_filter.append(good_lines[0])
这也应该比O(nlog n)和O(n^2)更有效,尽管它需要RAM中文件的所有内容
如果您有除猫
和狗
之外的其他“类”,并且您希望输出所有好猫
行,除非主题id
也是好狗
,您可以通过以下方式修改上述代码:
is_good_cat = any('CAT' in line for line in good_lines)
is_good_dog = any('DOG' in line for line in good_lines)
if is_good_cat and not is_good_dog:
file_filter.extend(line for line in good_lines if 'CAT' in good_lines)
(您需要使用.extend
和循环,因为我们不再知道要写入哪一行,所以您必须对它们进行筛选。当前输出中列出的两个项目都是匹配的,那么为什么您应该只得到一个呢?因为第二个项目包含good和dog,dog在这个字符串中的位置?-ID2_1234_CAT_ANIMAL_good_3ID2_1234_dog_ANIMAL_好的_0
因为它的名称与您的问题中的ID2 _1234
相同。我现在正在研究这个问题。谢谢。它成功了。只需更改文件_过滤器。追加(好的_行[0])
@John哦,是的,出于某种原因,我正在考虑一个文件。无论如何,我建议你花点时间尝试一下itertools.groupby
和这个模块。作为一个模块,它真的很有帮助。谢谢。但是我有一个问题,为什么只在好的方面与'CAT'进行比较[0]
。如果CAT
在好的线路的其他位置
@John出现了len(好的线路)的情况,会发生什么==1
因此您知道好的行
只包含一个元素。现在,如果您的输入可以在多行中包含相同的主题id和好的cat,那么您必须更改它,但具体如何更改取决于您想如何处理该情况。@John I用可能的解决方案更新了答案。
is_good_cat = any('CAT' in line for line in good_lines)
is_good_dog = any('DOG' in line for line in good_lines)
if is_good_cat and not is_good_dog:
file_filter.extend(line for line in good_lines if 'CAT' in good_lines)