gpt4 book ai didi

Python:创建对象引用列表

转载 作者:太空宇宙 更新时间:2023-11-04 07:18:58 25 4
gpt4 key购买 nike

我想清理我编写的一些代码,以扩展我正在尝试做的事情的规模。为此,我想理想地创建一个对象引用列表,以便我可以使用循环系统地设置对象,而不必实际将对象放入列表中。我已经了解了 Python 处理引用和传递的方式,但还没有完全找到有效执行此操作的方法。

为了更好地展示我正在尝试做的事情:

我正在使用 Bokeh ,并想设置大量的选择框。每个盒子看起来像这样

select_one_name = Select(
title = 'test',
value = 'first_value',
options = ['first_value', 'second_value', 'etc']
)

设置每个选择都很好,当我只有几个时,但当我有 20 个时,我的代码变得非常长且笨拙。我想做的是有一个 sample_list = [select_one_name, select_two_name, etc] 的列表,然后我可以遍历它,以设置每个 select_one_name< 的值select_two_name 等。但是,我想让我的引用 select_one_name 仍然指向正确的值,而不是必须通过调用 来引用该值sample_list[0].

我不确定这是否可行——如果有比创建引用列表更好的方法,请告诉我。我知道我可以只创建一个对象列表,但我正在努力避免这种情况。

作为引用,我使用的是 Python 2.7、Anaconda 发行版、Windows 7。谢谢!


跟进@Alex Martelli 的以下帖子:

我认为这可能行不通的原因是,当我尝试使用列表列表进行小型测试时,我没有得到想要的结果。演示

x = [1, 2, 3]
y = [4, 5, 6]

test = [x, y]
test[0].append(1)

结果为 x = [1, 2, 3, 1] 但如果相反,我使用 test[0] = [1, 2],则 x 仍然是 [1, 2, 3],尽管 test 本身反射(reflect)了变化。

平行回到我原来的例子,我认为我会看到与设置为相等的相同结果。这不是真的吗?

最佳答案

每个 Python list always 在内部都是一个引用数组(在 CPython 中,毫无疑问你正在使用什么,在 C 级别它是一个数组 PyObject* -- “指向 Python 对象的指针”)。

不会隐式创建对象的副本:而是(同样,在 CPython 中)当您将“对象”(实际上是对它的引用)添加到列表时,每个对象的引用计数都会增加。事实上,当您确实需要一个对象的副本时,您需要专门请求一个(通常使用 copy 模块,或者有时使用特定类型的复制方法)。

对同一个对象的多个引用在内部是指向完全相同内存的指针。如果一个对象是可变的,那么改变它会通过对它的所有引用反射(reflect)出来。当然,有些不可变对象(immutable对象)(字符串、数字、元组等)无法应用此类更改。

所以当你这样做时,例如,

sample_list = [select_one_name, select_two_name, etc]

每个名称(只要它在范围内)仍然指的是与 sample_list 中相应项目完全相同的对象。

换句话说,只要存在对同一对象的两个引用,使用 sample_list[0]select_one_name 是完全等价的。

IOW squared,您声明的目的已经由 Python 最基本的语义实现。现在,请编辑 Q 以澄清您观察到的哪些行为似乎与此相矛盾,以及您认为应该观察(和希望)的行为,我们可能会进一步提供帮助 - - 因为在这一点上,所有上述观察结果都等于“你得到了你所要求的语义”所以“保持稳定”是我实际上可以建议的!-)

已添加(这里的答案比下面的评论更好:-):注意对变异操作的关注。 OP 尝试了 test[0]= somelist 然后是 test[0].append 并看到 somelist 相应地发生了变化;然后尝试 test[0] = [1, 2] 并惊讶地看到 somelist not 改变了。但那是因为对引用的赋值并不是对引用用来指示的对象的变异操作!它只是重新定位引用,减少先前引用的对象的引用计数,仅此而已。

如果你想改变一个现有的对象(它首先需要是一个可变的,但是 list 满足这一点),你需要对其执行改变操作(通过任何引用,无所谓)。例如,除了 append 和许多其他命名方法之外,列表上的一个变异操作是分配给 slice,包括表示为 [ 的整个列表切片: ]。所以,test[0][:] = [1,2] 实际上会改变 somelist——与 test 非常不同[0] = [1,2] 分配给一个引用,给一个切片。

关于Python:创建对象引用列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28196463/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com