【问题标题】:Function only returns desired value once函数只返回一次想要的值
【发布时间】:2018-10-02 14:09:23
【问题描述】:

我创建了一个脚本,它将在目标文件中搜索关键字。如果该关键字在某一行文本上,它将获取整个文本并返回不包含该关键字的行的其余部分。例如,如果有一行文字说:

Title: Useless Data

那么脚本将只获取“无用数据”部分并将其附加到列表中。它会对文件中出现“title”一词的每个位置执行此操作。

脚本如果只运行一次从文件中获取几行并将它们输出到一个列表中是成功的,但是我想在文件中搜索两个关键词:标题和图标,然后将标题压缩到相应的图标.因此,如果我采用如下所示的一行文本:

LINE 1:
Title: Useless Data
Icon: Fairly upset programmer
Index: 12
filler data:
LINE 2:
Title: Line 2
Icon: Pancho
Index: 69
filler data:

输出应该是:

list1 = ['Useless Data', 'Line 2']
list2 = ['Fairly upset programmer', 'Pancho']

然后我想将它们压缩成一个如下所示的字典:

final_dict = {'Useless Data' : 'Line 2', 'Fairly upset programmer': 'Pancho'}

title_list = {}
target_file = open('Meta.txt', 'r')

# Searches for word in a line and removes all the useless data
def splitter(files, word):
    output = []
    for line in files:
        if word in line:
            output.append(line.split(':')[1].replace('\n', '').strip())
        else:
            continue
    print(output)
    return output

split1 = splitter(target_file, 'icon')
split2 = splitter(target_file, 'title')
final = zip(split1, split2)

【问题讨论】:

  • 你应该使用for line in files.readlines():
  • @Bazingaa:不,他们不应该。
  • 输出有什么问题?是 zip 还是您的拆分器功能的问题?
  • 那个“文本行”看起来像 10 行不是一个,所以不清楚你在说什么。
  • splitter 函数的顶部尝试files.seek(0)。第一次运行函数时,您正在耗尽文件迭代器对象

标签: python function file


【解决方案1】:

您的代码中有两个问题:首先,您使用的是小写的icontitle,而您的文件包含大写的IconTitle。字符串在 python 中区分大小写,因此两者不相同。其次,在第一次调用函数读取文件内容后,由于@roganjosh 在下面的 cmets 中指定的原因,第二次使用 target_file 无法正常工作。因此,您有许多其他选择中的两个:1) 每次在函数中读取文件或 2) 使用 files.seek(0)。下面提供了两种解决方案。

title_list = {}

# Searches for word in a line and removes all the useless data
def splitter(word):
    target_file = open('Meta.txt', 'r')
    output = []
    for line in target_file:
        if word in line:
            output.append(line.split(':')[1].replace('\n', '').strip())
        else:
            continue

    target_file.close()
    return output

split1 = splitter('Icon')
split2 = splitter('Title')

final = dict([iter(split2), iter(split1)])
print (final)


{'Useless Data': 'Line 2', 'Fairly upset programmer': 'Pancho'}

@roganjosh 使用 files.seek(0) 建议的替代解决方案

title_list = {}

target_file = 'Meta.txt'

# Searches for word in a line and removes all the useless data
def splitter(files, word):
    files.seek(0)
    output = []
    for line in target_file:
        if word in line:
            output.append(line.split(':')[1].replace('\n', '').strip())
        else:
            continue
    return output

with open(target_file) as infile:
    split1 = splitter(infile, 'Icon')
    split2 = splitter(infile, 'Title')
    final = dict([iter(split2), iter(split1)])
print (final)

【讨论】:

  • 我不喜欢您在函数中打开文件的解决方案,我认为将文件对象作为函数可重用性的参数传递是有道理的。在函数的开头尝试我的files.seek(0) 解决方案,然后将files 作为参数放回去。我认为这应该可行。
  • 您能否将您的解决方案添加为我的问题的编辑?
  • 因为它是同一个文件对象多次传递给函数,在第一次迭代之后,您现在指向文件的末尾,因此您无法再读取任何行。相反,您可以重置回顶部。
  • 奇怪的是,添加 target_file.seek(0) 解决了这个问题。您的解决方案也解决了这个问题。谢谢!
  • @Andromeda 请看我上面的评论来解释发生了什么
猜你喜欢
  • 2017-02-25
  • 2014-01-03
  • 2015-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
相关资源
最近更新 更多