列表中每个单词的平均字符数

4

我是新手Python程序员,需要计算列表中每个单词的平均字符数。

以下是相关定义和辅助函数 clean_up

令牌(token)是调用文件行字符串方法split所得到的字符串。

单词(word)是非空的标记,且不完全由标点符号构成。使用辅助函数clean_up从单词中删除标点符号,并通过str.split查找标记以寻找文件中的“单词”。

句子是以(但不包括)字符.或文件结束符为终止符的字符序列,不包含开头或结尾的空格且不为空。

这是我大学计算机科学课程的作业问题。

clean_up函数如下:

def clean_up(s):
    punctuation = """!"',;:.-?)([]<>*#\n\"""
    result = s.lower().strip(punctuation)
    return result

我的代码是:

def average_word_length(text):
    """ (list of str) -> float

    Precondition: text is non-empty. Each str in text ends with \n and at
    least one str in text contains more than just \n.

    Return the average length of all words in text. Surrounding punctuation
    is not counted as part of the words. 


    >>> text = ['James Fennimore Cooper\n', 'Peter, Paul and Mary\n']
    >>> average_word_length(text)
    5.142857142857143 
    """

    for ch in text:
        word = ch.split()
        clean = clean_up(ch)
        average = len(clean) / len(word)
    return average

我得到了5.0的结果,但是我非常困惑,希望能得到一些帮助 :) PS 我正在使用Python 3


1
你想要 float(len(word)) - Hoopdady
@Hoopdady OP正在使用Python3。 - Ashwini Chaudhary
3
这只是给出输入中最后一项的平均值。 - M4rtini
for 循环中使用 yield average 可以创建一个不错的生成器。 - Adam Smith
哦,真不错,我不知道Python3不支持整数除法。哦对了,我刚刚发现平均值在循环内部计算。 - Hoopdady
1
@Hoopdady 是的,这就是为什么在Python2中from __future__ import division有效。Python3才是未来!!! :) - Adam Smith
2个回答

6

让我们使用引入和生成器表达式来整理一些函数,好吗?

import string

def clean_up(s):
    # I'm assuming you REQUIRE this function as per your assignment
    # otherwise, just substitute str.strip(string.punctuation) anywhere
    # you'd otherwise call clean_up(str)
    return s.strip(string.punctuation)

def average_word_length(text):
    total_length = sum(len(clean_up(word)) for sentence in text for word in sentence.split())
    num_words = sum(len(sentence.split()) for sentence in text)
    return total_length/num_words

你可能会注意到,这实际上会压缩成一个长度不可读的单行代码:
average = sum(len(word.strip(string.punctuation)) for sentence in text for word in sentence.split()) / sum(len(sentence.split()) for sentence in text)

这是令人恶心和让人反感的行为,所以你不应该这样做。可读性很重要,所有这些。


5
这是一种简洁而易于理解的方法,可以解决你的问题。
def clean_up(word, punctuation="!\"',;:.-?)([]<>*#\n\\"):
    return word.lower().strip(punctuation)  # you don't really need ".lower()"

def average_word_length(text):
    cleaned_words = [clean_up(w) for w in (w for l in text for w in l.split())]
    return sum(map(len, cleaned_words))/len(cleaned_words)  # Python2 use float

>>> average_word_length(['James Fennimore Cooper\n', 'Peter, Paul and Mary\n'])
5.142857142857143

所有这些前提条件的负担都落在你身上。

@AshwiniChaudhary 或者一个列表推导式。 :) - Inbar Rose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接