在函数内部操作时列表会发生变化

List is getting changed when manipulated inside function

提问人:Toby Clark 提问时间:12/5/2022 最后编辑:Toby Clark 更新时间:12/5/2022 访问量:43

问:

我有一个函数,旨在递归地查找对象数组中的值,并返回具有类似 y0 的所有变量的字符串。这一切都很好,但是,当作数组时,它会操作已输入到其中的数组,尽管我制作了数组的副本以防止此问题。

这意味着,当您运行给定的代码时,它会将 tmp 更改为具有不同的文本值。我知道当它设置为递归函数的输出时,错误在第 26 行,但是我不确定为什么考虑它应该操作数组的副本。BOLD_OBJ["text"]

def recursiveScanText(BOLD_OBJ_LIST:list, Y_VALUE: int, output: list):
    if BOLD_OBJ_LIST[0]["y0"] == Y_VALUE:
        output.append(BOLD_OBJ_LIST[0]["text"])
        BOLD_OBJ_LIST.pop(0)
        if BOLD_OBJ_LIST == []:
            return output
        output = recursiveScanText(BOLD_OBJ_LIST, Y_VALUE, output)
        return output
    else:
        return output
 
def mergeSimilarText(BOLD_OBJ_LIST: list):
    """Merges the objects of a list of objects if they are at a similar (±5) Y coordinate"""
    OUTPUT = []
    RECURSIVE_SCAN_OUTPUT = []
    BOLD_OBJ_LIST = BOLD_OBJ_LIST.copy()
 
    for BOLD_OBJ_INDEX in range(len(BOLD_OBJ_LIST)):
        if len(BOLD_OBJ_LIST) > 0 and BOLD_OBJ_INDEX < len(BOLD_OBJ_LIST):
            BOLD_OBJ = BOLD_OBJ_LIST[0]
 
            BOLD_CHAR_STRING = recursiveScanText(BOLD_OBJ_LIST, BOLD_OBJ_LIST[BOLD_OBJ_INDEX]["y0"], RECURSIVE_SCAN_OUTPUT)
 
            RECURSIVE_SCAN_OUTPUT = []
 
            BOLD_OBJ["text"] = "".join(BOLD_CHAR_STRING)
            OUTPUT.append(BOLD_OBJ)
 
    return OUTPUT
 
tmp = [
{'y0': 762.064, 'text': '177'}, 
{'y0': 762.064,  'text': '7'}, 
{'y0': 114.8281, 'text': 'Q'}, 
{'y0': 114.8281, 'text': 'u'}, 
{'y0': 114.8281, 'text': 'e'}, 
{'y0': 114.8281, 'text': 's'}, 
{'y0': 114.8281, 'text': 't'}, 
{'y0': 114.8281, 'text': 'i'}, 
{'y0': 114.8281, 'text': 'o'}, 
{'y0': 114.8281, 'text': 'n'}, 
{'y0': 114.8281, 'text': ' '}, 
{'y0': 114.8281, 'text': '1'}, 
{'y0': 114.8281, 'text': '7'}, 
{'y0': 114.8281, 'text': ' '}, 
{'y0': 114.8281, 'text': 'c'}, 
{'y0': 114.8281, 'text': 'o'}, 
{'y0': 114.8281, 'text': 'n'}, 
{'y0': 114.8281, 'text': 't'}, 
{'y0': 114.8281, 'text': 'i'}, 
{'y0': 114.8281, 'text': 'n'}, 
{'y0': 114.8281, 'text': 'u'}, 
{'y0': 114.8281, 'text': 'e'}, 
{'y0': 114.8281, 'text': 's'}, 
{'y0': 114.8281, 'text': ' '}, 
{'y0': 114.8281, 'text': 'o'}, 
{'y0': 114.8281, 'text': 'n'}, 
{'y0': 114.8281, 'text': ' '}, 
{'y0': 114.8281, 'text': 'p'}, 
{'y0': 114.8281, 'text': 'a'}, 
{'y0': 114.8281, 'text': 'g'}, 
{'y0': 114.8281, 'text': 'e'}, 
{'y0': 114.8281, 'text': ' '}, 
{'y0': 114.8281,'text': '9'}]
 
print(mergeSimilarText(tmp))
print(tmp)

一些注意事项:我尝试更改为,但仍然无法解决它。另外,我不需要深度复制,因为它是一个字典数组而不是数组数组BOLD_OBJ_LIST = BOLD_OBJ_LIST.copy()tmp = BOLD_OBJ_LIST.copy()

Python 数组 列表 数据操作

评论

1赞 Wolric 12/5/2022
请发布您的代码,而不是提供链接。此外,请考虑修剪代码以创建 MCVE
0赞 Toby Clark 12/5/2022
完成后,对如何解决问题有任何建议吗?
1赞 Yevhen Kuzmovych 12/5/2022
您的列表本身不会更改,但其中的词典会更改。因为不会进行深度复制。看到这个.copy()
0赞 sahasrara62 12/5/2022
使用 deepcopy as 和from copy import deepcopyBOLD_OBJ_LIST = deepcopy(BOLD_OBJ_LIST)

答:

1赞 Wolric 12/5/2022 #1

copy对列表进行浅拷贝,即如果该列表中有可变元素,则仅复制引用。

您需要使用:deepcopy

from copy import deepcopy

BOLD_OBJ_LIST = deepcopy(BOLD_OBJ_LIST)

这将以递归方式创建所有元素的副本。