使用Word Wrapping的Python Word处理函数

问题描述 投票:1回答:2

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

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

  • 输出的每个字符串中的每个字之间必须只有一个空格。
  • 每个单词将由英文字母表中的小写字母组成。
  • 没有标点符号。
  • 可以假设每个单词的最大长度是恒定的。
  • 没有一个单词会比一行中给定的最大字符长度长。
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
python string list function word-wrap
2个回答
2
投票

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

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

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

第二个错误只是你没有将空格连接到你的行字符串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()

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 cuckoo','七个你好']

© www.soinside.com 2019 - 2024. All rights reserved.