列表理解中的浅表或深表副本 [英] Shallow or deep copy in a list comprehension

查看:66
本文介绍了列表理解中的浅表或深表副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您在python中有一个列表(原始),例如:

If you have a list (Original) in python like:

class CustomID (object):                   
    def __init__(self, *args):
        self.ID = ''
        self.manymore = float()
        self.visited = False
        self.isnoise = False
IDlist = ['1','2','3','4','5','6','7','8','9','10']
Original = list()
for IDs in IDlist:
    NewObject = CustomID()
    NewObject.ID = IDs
    Original.append(NewObject)

,如果您对新列表做了理解,并且对要理解的子列表使用了函数:

and if you do a comprehension for a new list and a function to use over the comprehension sublist:

def Func(InputList=list()):
    for objects in InputList:
        objects.visited = True
    return InputList
New_List = [member for member in Original if (int(member.ID)>5)]
ThirdList = Func(New_List)

这是(New_List)导致原始列表的浅表副本还是深表副本?如果原始列表包含对象,则这对我而言很重要,可以在代码中更改其属性以遵循New_List创建(ThirdList).New_list发送到一个函数,该函数将更改属性.问题是,如果您尝试对具有不同理解的同一函数重用原始列表(假设为 (members>4)).

Is this (New_List) resulting in a shallow or deep copy of the original list? The matter is relevant for me, if the original list contains objects, which attributes can change in the code to follow New_List creation (ThirdList). New_list is send to a function, which will change the attributes. The question is if you try to reuse the original list for the same function with different comprehension (lets say (members>4).

New_List = [member for member in Original if (int(member.ID)>4)]

实际上:

print New_List[3].visited

给出了真.

推荐答案

您正在创建经过过滤的浅表副本.

You are creating a shallow, filtered copy.

您的循环不会创建 member 的副本,而是直接引用它们.

Your loop doesn't create copies of member, it references them directly.

并不是您需要创建副本,原始列表中的所有对象都是不可变的整数.而且,CPython会实习小的整数,创建副本只会导致完全相同的对象用于这些对象.

Not that you would need to create copies, all objects in your original list are immutable integers. Moreover, CPython interns small integers, creating copies would only result in the exact same objects being used for these.

为说明起见,请尝试创建包含可变对象的列表的副本.在这里,我使用了字典:

To illustrate, try to create a copy of a list containing mutable objects instead. Here I used a dictionary:

>>> sample = [{'foo': 'bar'}]
>>> copy = [s for s in sample]
>>> copy[0]['spam'] = 'eggs'
>>> copy.append({'another': 'dictionary'})
>>> sample
[{'foo': 'bar', 'spam': 'eggs'}]

copy 列表是一个新的列表对象,其中包含对 sample 中包含的同一词典的引用.更改该词典会同时反映在 copy sample 中,但是追加到 copy 不会更改原始列表.

The copy list is a new list object containing a reference to the same dictionary contained in sample. Altering that dictionary is reflected in both copy and sample, but appending to copy doesn't alter the original list.

关于更新后的循环代码,您的示例将生成一个仍共享对象的 New_List 列表,而 New_List [3] .visited 实际上是 True :

As for your updated loop code, your sample produces a New_List list that still shares objects, and New_List[3].visited is in fact True:

>>> New_List[3].ID
'8'
>>> New_List[3].visited
True

因为它仍然是在原始的索引7中找到的同一对象:

because it is still the same object found in Original at index 7:

>>> New_List[3] is Original[7]
True

与仍在索引2的 ThirdList 中找到的同一对象

which is the same object still found in ThirdList at index 2:

>>> ThirdList[2] is New_List[3]
True

这篇关于列表理解中的浅表或深表副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆