繁体   English   中英

在python中正确初始化列表

[英]Proper initialization of lists in python

我正在尝试实现文本对齐算法

    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变量的作用域定义或初始化方面,我在做错什么?

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

二维数组的正确初始化如下所示:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM