在python中正确初始化列表

时间:2017-10-05 22:05:09

标签: python

我正在尝试实施text justification algorithm

    def line_cost(words, max_width):
        """
           words are list of words (strings) to be justified
        """
        if not words:
            return 0
        if not words_fit(words, max_width):
            return float('+Inf')
        return extra_spaces_for_line(words, max_width)**3

    def words_fit(words, max_width):
        return extra_spaces_for_line(words, max_width) > 0

    def extra_spaces_for_line(words, max_width):
        return max_width - len(" ".join(words))

    def cost_words_itoj_in_line(i, j, words, max_width):
        tentative = line_cost(words[i:j], max_width)
        if tentative < float('+Inf') and j == len(words):
            return 0
        return tentative

    def cost_lines(words, max_width):
        cost_itoj = [[float('+Inf')] * (len(words) + 1)] * (len(words) + 1)
        for i in range(len(words) + 1):
            for j in range(i, len(words) + 1):
                cost_itoj[i][j] = cost_words_itoj_in_line(
                    i, j, words, max_width)
                # print(cost_itoj[i][j]) # If I uncomment this line, I see the value of cost_itoj just fine, most of them non-zero.
        return cost_itoj

有了这个定义,当我打电话:

>>> words = "Never forget what you are, for surely the world will not. Make it your strength. Then it can never be your weakness. Armour yourself in it, and it will never be used to hurt you.".split()
>>> cost_lines(words, 15)

我得到的所有列表都填充了零。

考虑另一个版本的cost_lines函数:

def cost_lines(words, max_width):
            cost_itoj = [[float('+Inf')] * (len(words) + 1)] * (len(words) + 1)
            for i in range(len(words) + 1):
                for j in range(i, len(words) + 1):
                    yield cost_words_itoj_in_line(
                        i, j, words, max_width)

然而,有了这个定义,当我打电话

>>> list(cost_lines(words, 15))

我得到一份充满适当成本价值的清单清单。在cost_itoj的第一个定义中cost_lines变量的范围或初始化方面,我做错了什么?

1 个答案:

答案 0 :(得分:1)

范围与此无关:您只是无法正确初始化数据结构。 cost_itoj = [[float('+Inf')] * (len(words) + 1)] * (len(words) + 1)创建一个Inf的列表,然后创建一个列表,其中包含对该ONE内部列表的多个引用,而不是您可能想要的二维数组。换句话说,cost_itoj[1][x]引用与cost_itoj[2][x]相同的列表元素。您正在计算所有正确的值,但每行都会覆盖最后一行的结果;我想你的最后一行都是零。

2D阵列的正确初始化如下所示:

cost_itoj = [[float('Inf')] * (len(words)+1) for _ in range(len(words)+1)]

其中_是循环所需的虚拟变量。