带文字包装的Python文字处理功能

时间:2019-04-04 02:15:15

标签: python string list function word-wrap

我正在构建文字处理器,并试图实现自动换行功能。

给定一行中最多字符数,然后是单词列表,我想返回一个字符串集合,其中每行包含尽可能多的单词,并用空格连接。每个字符串的长度不应超过最大长度。

  • 输出的每个字符串中的每个单词之间必须有一个空格。
  • 每个单词都由英语字母中的小写字母组成。
  • 没有标点符号。
  • 每个单词的最大长度可以假定是恒定的。
  • 没有一个单词会超过一行中给定的最大字符长度。
import sys

# Prints to standard output.
def wrapLines(line_length, words):
  curr_line = ""
  for word in words:
    if len(curr_line) + len(word) >= line_length:
      curr_line = ""
    else:
      curr_line += word
      print curr_line


def main():
  first_line = None
  words = []

  first_arg = True
  for line in sys.stdin:
    if len(line.strip()) == 0:
      continue

    line = line.rstrip()

    if first_arg:
      lineLength = line
      first_arg = False
    else:
      words.append(line)

  wrapLines(lineLength, words)

main()

输入:

13
abc
xyz
foobar
cuckoo
seven
hello

我的输出将继续打印彼此附加的所有单词,而不是换行。

abc
abcxyz
abcxyzfoobar
abcxyzfoobarcuckoo
abcxyzfoobarcuckooseven
abcxyzfoobarcuckoosevenhello

预期输出:

abc xyz
foobar cuckoo
seven hello

2 个答案:

答案 0 :(得分:2)

那里有几个问题- 最重要的是,您正在阅读stdin中的第一行,并将其用作lineLength,但您请勿将其转换为数字。因此,您在lineLength(和包装器函数内的line_length)变量中的值是一个字符串-和比较

 if len(curr_line) + len(word) >= line_length:

始终将左侧建议的输出行的长度与字符串进行比较-如果您使用的是最新版本的Python,则此行会出错,因为现在(正确地)禁止使用数字和字符串作为字符。但是,在Python 3中,此表达式始终为True-数字始终被视为比字符串多<-因此,永远不会运行超出限制的行的代码。

第二个错误是,您没有将空格连接到行字符串中,而yu只是将字词与+=连接在一起,却没有添加空格。

第三个错误是,您始终打印循环中正在计算的行-不管是否超过了行长。

最后,但并非最不重要的一点-正如我在上面的评论中所述:不再使用Python 2-他们之所以制作Python 3是有原因的,这是因为语言的发展。

而且,错误较少​​,但建议这样做:函数应只处理文本并返回数据-如果要打印结果,则可以从调用程序函数中打印它。这样,该功能就足够通用,可以在其他上下文中使用。

此外,Python应用程序的建议缩进大小为4。尽管使用2个空格是有效的代码,但实际上几乎没有在任何地方使用它(但在某些知名公司的私有代码中-但这是他们的业务)。

您的固定代码以及建议-在Python 2和3中均可使用

import sys

def wrapLines(line_length, words):
    curr_line = ""
    result = []
    for word in words:
        if len(curr_line) + len(word) + 1 >= line_length:
            result.append(curr_line)
            curr_line = ""
        else:
            curr_line += " " + word
    if curr_line:
        result.append(currline)
    return result


def main():
    first_line = None
    words = []

    first_arg = True
    for line in sys.stdin:
        if len(line.strip()) == 0:
            continue

        line = line.rstrip()

        if first_arg:
            line_length = int(line)
            first_arg = False
        else:
            words.append(line)

    print("\n".join(wrapLines(line_length, words)))


main()

答案 1 :(得分:0)

首先,据我所知,您没有指定所需的lineLength,因此我将根据您的预期输出来假设14。我个人认为这可以简化为一个循环遍历您输入单词列表的函数,如果可以在不超过行长的情况下添加它,它将添加到字符串中,否则会将字符串添加到我们的输出列表中(参见因为它无法处理下一个单词),然后重置字符串。我实现了while循环,因此在需要重置的迭代中,它不能简单地不增加计数器(在我的情况下,i),然后它将在下一次迭代中索引相同的位置,并且将第一个要添加到新重置的字符串的行。我在Python 3.X中进行了此操作,因此它可能无法在2.X中工作,但是如果是这种情况,它将是'{}'.format,而您可以使用%运算符。在循环的最后,还有另一个wrapped_words.append(current_line.strip()),因此我们也可以抓住最后一行。

我的解决方案:

words_input = ['13', 'abc', 'xyz', 'foobar', 'cuckoo', 'seven', 'hello']

def wrap_words(words_to_wrap, max_line_length):
    wrapped_words = []
    current_line = ''
    i = 0
    while i < len(words_to_wrap):
        if len(current_line) + len(words_to_wrap[i]) + 1 > max_line_length:  # +1 for the space
            wrapped_words.append(current_line.strip())
            current_line = ''
        else:
            current_line += '{} '.format(words_to_wrap[i])
            i += 1
    if len(current_line):
        wrapped_words.append(current_line.strip())
    return wrapped_words

print(wrap_words(words_input, 14))

输出:

  

['13 abc xyz','foobar杜鹃','七个你好']