Python 列表复制和切片修改原始列表

Python list copy and slice modifying original list

提问人:Segun Ojo 提问时间:3/28/2023 更新时间:3/28/2023 访问量:44

问:

我有一个列表,如下所示:

voting_records = [['1.', 'DIRECTOR', 'Management'],
 ['1', 'Allison Grant Williams', 'For'],
 ['2', 'Sheila Hartnett-Devlin', 'For'],
 ['3', 'James Jessee', 'For'],
 ['4', 'Teresa Polley', 'For'],
 ['5', 'Ashley T. Rabun', 'For'],
 ['6', 'James E. Ross', 'For'],
 ['7', 'Rory Tobin', 'For']]

我创建了这个列表的副本,名为使用列表推导:voting_records_short

cnames = ["Record","Proposal","Sponsor","VoteCast"]
voting_records_short = [record for record in voting_records if len(record) < len(cnames)]

然后我创建了一个切片并将其保存在 .然后,我在for循环中修改列表,如下所示:voting_records_shortdirectorsdirectors

if len(voting_records_short) == 0: pass
else:
    ifdirector = ["DIRECTOR" in record for record in voting_records_short]
    if True in ifdirector:
        directorindx = int(ifdirector.index(True))
        directorline = [voting_records_short[directorindx]]
        directors = voting_records_short[directorindx+1:]
        sponsoridx = cnames.index("Sponsor")
        for ls in range(len(directors)):
            directors[ls][0] = directorline[0][0] + directors[ls][0]
            directors[ls][1] = directorline[0][1] + " " +directors[ls][1]
            directors[ls].insert(sponsoridx,directorline[0][-1])

为什么在 for 循环中修改 directors 列表会同时修改列表,如下面的输出所示:voting_records_shortvoting_records

In [2]: voting_records
Out[2]: 
[['1.', 'DIRECTOR', 'Management'],
 ['1.1', 'DIRECTOR Allison Grant Williams', 'Management', 'For'],
 ['1.2', 'DIRECTOR Sheila Hartnett-Devlin', 'Management', 'For'],
 ['1.3', 'DIRECTOR James Jessee', 'Management', 'For'],
 ['1.4', 'DIRECTOR Teresa Polley', 'Management', 'For'],
 ['1.5', 'DIRECTOR Ashley T. Rabun', 'Management', 'For'],
 ['1.6', 'DIRECTOR James E. Ross', 'Management', 'For'],
 ['1.7', 'DIRECTOR Rory Tobin', 'Management', 'For']]

In [9]: voting_records_short
Out[9]: 
[['1.', 'DIRECTOR', 'Management'],
 ['1.1', 'DIRECTOR Allison Grant Williams', 'Management', 'For'],
 ['1.2', 'DIRECTOR Sheila Hartnett-Devlin', 'Management', 'For'],
 ['1.3', 'DIRECTOR James Jessee', 'Management', 'For'],
 ['1.4', 'DIRECTOR Teresa Polley', 'Management', 'For'],
 ['1.5', 'DIRECTOR Ashley T. Rabun', 'Management', 'For'],
 ['1.6', 'DIRECTOR James E. Ross', 'Management', 'For'],
 ['1.7', 'DIRECTOR Rory Tobin', 'Management', 'For']]

我原以为只会修改列表(也许,但我不确定),但为什么要修改原始列表?我很感激任何帮助?directorsvoting_records_shortvoting_records

列表 可变 就地

评论

0赞 juanpa.arrivillaga 3/28/2023
因为它们都引用相同的子列表。您从未在任何地方复制过任何子列表。

答:

1赞 harriet 3/28/2023 #1

您正在迭代原始voting_records,并将对每条记录的引用存储在新列表中;因此,对带有引用的记录所做的更改将修改两个列表 - 如上所述: DeepCopy

from copy import deepcopy
copy_records = deepcopy(voting_records)
voting_records_short = [record for record in copy_records if len(record) < len(cnames)]

运行代码后:

[['1.', 'DIRECTOR', 'Management'], ['1', 'Allison Grant Williams', 'For'], ['2', 'Sheila Hartnett-Devlin', 'For'], ['3', 'James Jessee', 'For'], ['4', 'Teresa Polley', 'For'], ['5', 'Ashley T. Rabun', 'For'], ['6', 'James E. Ross', 'For'], ['7', 'Rory Tobin', 'For']]
[['1.', 'DIRECTOR', 'Management'], ['1.1', 'DIRECTOR Allison Grant Williams', 'Management', 'For'], ['1.2', 'DIRECTOR Sheila Hartnett-Devlin', 'Management', 'For'], ['1.3', 'DIRECTOR James Jessee', 'Management', 'For'], ['1.4', 'DIRECTOR Teresa Polley', 'Management', 'For'], ['1.5', 'DIRECTOR Ashley T. Rabun', 'Management', 'For'], ['1.6', 'DIRECTOR James E. Ross', 'Management', 'For'], ['1.7', 'DIRECTOR Rory Tobin', 'Management', 'For']]