从在线源代码中读取特定单词

2024-04-23 09:28:23 发布

您现在位置:Python中文网/ 问答频道 /正文

以下是文本文件的内容abc.txt文件

This is before the start and should be ignored.
So should this
and this


*** START OF SYNTHETIC TEST CASE ***
a ba bac
*** END OF SYNTHETIC TEST CASE ***

This is after the end and should be ignored too.
Have a nice day.

我需要编写一个函数,get\u words\u from\u file(filename),返回小写单词列表,如下例所示。函数应该只处理起始标记行和结束标记行之间的行,并使用下面提供的单词定义。你知道吗

我提供了以下正则表达式来描述所需的内容。我不需要理解正则表达式是如何工作的,我只需要理解下面给出的对findall的调用将返回给定行字符串中相关单词的列表。你知道吗

words_on_line = re.findall("[a-z]+[-'][a-z]+|[a-z]+[']?|[a-z]+", line)

.Include all lower-case character sequences including those that contain a 
- or ' character and those that end with a ' character. 
.Words that end with a - MUST NOT be included. 
.The words should be in the same order as they occur in the file.
.There must be no more than 9 CONSTANTS declared.
.Functions must be no longer than 20 statements.
.Functions must not have more than 3 parameters.

Test Code:

filename = "abc.txt"
words2 = get_words_from_file(filename)
print(filename, "loaded ok.")
print("{} valid words found.".format(len(words2)))
print("Valid word list:")
print("\n".join(words2))

Expected Output:

abc.txt loaded ok.
3 valid words found.
Valid word list:
a
ba
bac

我的代码如下:

def stripped_lines(lines):
    for line in lines:
        stripped_line = line.rstrip('\n')
        yield stripped_line

def lines_from_file(fname):
    with open(fname, 'rt', encoding='utf8') as flines:
        for line in stripped_lines(flines):
            yield line

def is_marker_line(line, start='***', end='***'):
    '''
    Marker lines start and end with the given strings, which may not
    overlap.  (A line containing just '***' is not a valid marker line.)
    '''
    min_len = len(start) + len(end)
    if len(line) < min_len:
        return False
    return line.startswith(start) and line.endswith(end)

def advance_past_next_marker(lines):
    '''
    Advances the given iterator through the first encountered marker
    line, if any.
    '''
    for line in lines:
        if is_marker_line(line):
            break

def lines_before_next_marker(lines):
    '''
    Yields all lines up to but not including the next marker line.  If
    no marker line is found, yields no lines.
    '''
    valid_lines = []
    for line in lines:
        if is_marker_line(line):
            break
        valid_lines.append(line)
    else:
        # `for` loop did not break, meaning there was no marker line.
        valid_lines = []
    for content_line in valid_lines:
        yield content_line

def lines_between_markers(lines):
    '''
    Yields the lines between the first two marker lines.
    '''
    # Must use the iterator --- if it's merely an iterable (like a list
    # of strings), the call to lines_before_next_marker will restart
    # from the beginning.
    it = iter(lines)
    advance_past_next_marker(it)
    for line in lines_before_next_marker(it):
        yield line

def words(lines):
    text = '\n'.join(lines).lower().split()
    # Same as before...

def get_words_from_file(fname):
    for word in words(lines_between_markers(lines_from_file(fname))):
        return word

filename = "abc.txt"
words2 = get_words_from_file(filename)
print(filename, "loaded ok.")
print("{} valid words found.".format(len(words2)))
print("Valid word list:")
print("\n".join(words2))

My Crappy Output

 Traceback (most recent call last):
  File "C:/Users/Jill/SQ4.1(2).py", line 67, in <module>
    words2 = get_words_from_file(filename)
  File "C:/Users/Jason/SQ4.1(2).py", line 63, in <module>
    for word in words(lines_between_markers(lines_from_file(fname))):
builtins.TypeError: 'NoneType' object is not iterable

你能帮我修改密码吗?我完全不知所措。你知道吗


Tags: theinfromforisdeflinefilename
1条回答
网友
1楼 · 发布于 2024-04-23 09:28:23

我已经改变了原来的代码一点,试试下面。你知道吗

def stripped_lines(lines):
for line in lines:
    stripped_line = line.rstrip('\n')
    yield stripped_line


def lines_from_file(fname):
    with open(fname, 'rt') as flines:
        for line in stripped_lines(flines):
            yield line


def is_marker_line(line, start='***', end='***'):
    '''
    Marker lines start and end with the given strings, which may not
    overlap.  (A line containing just '***' is not a valid marker line.)
    '''
    min_len = len(start) + len(end)
    if len(line) < min_len:
        return False
    return line.startswith(start) and line.endswith(end)


def advance_past_next_marker(lines):
    '''
    Advances the given iterator through the first encountered marker
    line, if any.
    '''
    for line in lines:
        if is_marker_line(line):
            break


def lines_before_next_marker(lines):
    '''
    Yields all lines up to but not including the next marker line.  If
    no marker line is found, yields no lines.
    '''
    valid_lines = []
    for line in lines:
        if is_marker_line(line):
            break
        valid_lines.append(line)
    else:
        # `for` loop did not break, meaning there was no marker line.
        valid_lines = []
    for content_line in valid_lines:
        yield content_line


def lines_between_markers(lines):
    '''
    Yields the lines between the first two marker lines.
    '''
    # Must use the iterator  - if it's merely an iterable (like a list
    # of strings), the call to lines_before_next_marker will restart
    # from the beginning.
    it = iter(lines)
    advance_past_next_marker(it)
    for line in lines_before_next_marker(it):
        yield line


def words(lines):
    text = '\n'.join(lines).lower().split()
    return text

def get_words_from_file(fname):
    return words(lines_between_markers(lines_from_file(fname)))

filename = "abc.txt"
all_words = get_words_from_file(filename)
print(filename, "loaded ok.")
print("{} valid words found.".format(len(all_words)))
print("Valid word list:")
print("\n".join(all_words))

输出将低于

('abc.txt', 'loaded ok.')
3 valid words found.
Valid word list:
a
ba
bac

相关问题 更多 >