无法在文本文件中找到字符串

时间:2015-12-03 22:44:33

标签: python string file python-2.7 search

鉴于项目编号列表,我正在尝试搜索带有最近项目编号列表的文本文件,并在最近的列表中标识任何项目编号。然后,我想要添加最近列表中尚未包含的任何项目。

我的代码如下,它似乎没有在文本文件中找到任何内容。为什么它不起作用?

def filter_recent_items(items):
    recentitems = []
    with open('last 600 items.txt', 'r+') as f:
        for item in items:
            if item['ID'] in f:
                print 'In! --', item['ID']
            else:
                recentitems.append(item['ID'])
                print 'Out ---', item['ID']
        for item in recentitems:
            f.write("%s\n" % item)


items = [ {'ID': 1}, {'ID': 'test2'} ]     
filter_recent_items(items)

例如,我的文本文件是:

test2

test1

1

但上面的代码返回

Out --- 1
Out --- test2

3 个答案:

答案 0 :(得分:6)

问题在于如何检查指定文本是否存在。在您的代码中f是一个文件对象,用于读取和写入文件。它不包含文件的内容。所以当你检查是否

str in f

它没有检查你的想法。 (详见下文。)

相反,您需要读取文件的行,然后遍历这些行并检查必要的字符串。实施例

with open('last 600 items.txt', 'r+') as f:
    lines = f.readlines()
    for l in lines:
        # check within each line for the presence of the items

在上面的代码中,f.readlines()使用文件对象来读取文件的内容并返回字符串列表,这些字符串是文件中的行。

已编辑(感谢Peter Wood)

Python Membership Details

在Python中,当您使用语法x in y时,它会检查两件事:

案例1 :首先检查y是否有__contains__(b)方法。如果是,则返回y.__contains__(x)的结果。

案例2 但是,如果y 有<{1}}方法,但确实定义了__contains__方法,相反,Python使用那个方法迭代__iter__的内容并返回y,如果在任何一点上迭代的值等于True。否则,它返回x

如果我们以您的代码为例,在某一点上,它会检查语句False的真实性。此处"test2" in ff类型的对象。 (Python File Object Description)。文件对象属于案例2(即他们file,他们__contains__

因此,代码将遍历每一行,并查看输入字符串是否与文件中的任何行相等。由于每一行都以char __iter__结尾,因此您的字符串永远不会返回\n

详细说明,虽然True会返回"test2" in "test2\n",但此处实际执行的测试是:True,即"test2" == "test2\n"

您可以手动测试文件的工作原理。例如,如果我们想查看False是否应该返回"test2" in f

True

您会注意到它打印出每一行(包括末尾的换行符),with open(filename) as f: x = iter(f) while(True): try: line = x.next() except: break print(line) print(line == "test2") 的结果始终为line == "test2"

如果我们尝试:False,则结果为"test2\n" in f

结束修改

答案 1 :(得分:2)

正如其他人所说,if "somestring" in f将永远失败。 f是一个文件对象,当您遍历它时,会生成一行文本。这些LINES中的一个或多个可能包含您的文本,因此您可以这样做:

if any("targetstring" in line for line in f):
    # success

f.read()f.readlines()方法相比,这是一种节省内存的方法,它们在执行任何操作之前都将整个文件流式传输到内存中。

@PeterWood在评论中指出,你的一些目标字符串实际上并不是字符串。你也应该看到这一点。 all(isinstance(item["ID"], str) for item in items)应为True

答案 2 :(得分:1)

打印出您的数据存储 f 。首先,我希望你有嵌入的换行符,以防止项匹配:“1”与“1 \ n”不匹配。其次,请注意**打开“给你一个生成器,而不是列表或元组。你不能多次扫描列表。在你以某种方式迭代它之前,你没有它的数据。

您需要使用代码将所有元素放入内存,例如

content = f.read().split("\n")
for item in items:
    if item["ID" in content: