2013-12-15 123 views
1

例如(从实际的使用大大简化):Python:有没有办法让所有对象的引用都引用另一个对象?

我为10,000引用到3个对象的一个​​列表:

a,b,c = {'font-size':1},{'font-size':2},{'font-size':2.3}` 
styles = [a,b,c,a,a,a,a,a,b,......] #10,000 

这节省了我的每创建一个新的字典的记忆10000个指标,因为它们都属于三种价值之一(实际上有数百种)。

现在我决定字体大小必须是int,所以我围绕c{'font-size':2}。但我希望所有c变成b,因为它们现在是同一个。

有没有一种方法(对整个列表进行彻底的比较,并比较每个值并在需要时将其替换,我知道它,但是如果我必须再次对很多对象再次执行,则会变得很慢),以使所有参考c参考b?我知道python保留垃圾清理这样的引用列表。或者也许c引用的对象可以依次自动引用b

编辑:我欣赏建议的解决方法,但正如在评论中所述,解决方法都让我遇到问题,我希望通过找到问题答案(改变内存消耗或时间消耗)通过Python引用列表引用或以某种方式在python内部重定向引用)。

+0

呢'C = B'做出任何帮助吗? –

+1

不,因为在'styles'中它仍然指'c',即'styles [2]是b == False' – Jeff

+1

据我所知,你所要求的是不可能的。 – mgilson

回答

0

重新分配c的值,然后重新分配的样式

c = b 
styles = [a,b,c,a,a,a,a,a,b,......] #10,000 

则C将指b中的值。这是一个解决方案,我能想到的

>>> a = [1,2,3] 
>>> b = [2,3,4] 
>>> c = [a,b] 
>>> b = a 
>>> c[1] 
[2, 3, 4] 
>>> b 
[1, 2, 3] 
>>> c = [a,b] 
>>> c[1] 
[1, 2, 3] 
+1

如前所述,缺少风格和比较每个值,我不知道如何分配样式。它在某个早期点被分配了值,在程序的其他地方,现在需要改变。我不能只做'styles = [.....]' – Jeff

+0

@Jeff:如果样式是在某个函数中赋值的,那么可以再次调用该函数,也许是 –

+0

'c = [a,b]'(第二个到最后的声明)? – falsetru

2

如何使用索引styles

template = a, b, c = {'font-size':1},{'font-size':2},{'font-size':2.3}` 
#styles = [a,b,c,a,a,a,a,a,b,......] 
styles = [0,1,2,0,0,0,0,0,1,......] 

c['font-size'] = 2 
# OR template[2]['font-size'] = 2 
# OR template[2] = template[1] 

缺点:

其他非关联化需要访问的实际值:template[styles[i]]代替styles[i]

+0

我喜欢'#OR template [2] = template [1]''的方法,但是我经常需要通过'styles'来知道每个相邻样式是否与前一样相同如果(如您所指出的)每次都必须将2对1解引用,则会变得缓慢。 – Jeff

+1

@Jeff,如果'styles = [1 if i == 2 else i for i in styles]'或'styles [:] = [1 if i == 2 else i for i in styles]',只检查索引,而不是内容? – falsetru

+0

可能更快,那么我的后备'for'循环,因为使用列表理解。 (并且可以使用索引和'=='来删除:'styles = [b if i is c else i for i in styles]',)我仍然坚持另一个不涉及重写整个列表的答案虽然。 – Jeff

0

我不知道我的理解,但如果你只有三种风格,你想取代以往b在使用C风格的Y的发生,你可以这样做:

a,b,c = {'font-size':1},{'font-size':2},{'font-size':2.3} 
styles = [a,b,c,a,a,a,a,a,b,c,a] 
for n,i in enumerate(styles): 
    if i==b: 
    styles[n]=c 
print styles 

>>>[{'font-size': 1}, {'font-size': 2.3}, {'font-size': 2.3}, ... 
+0

如上所述,“没有彻底清单并比较每个值并在需要时将其替换,我知道这些值,但是如果我必须再次对多个对象再次执行,则速度很慢”# – Jeff

0

什么

a, b, c = the_values = [{'font-size': 1}, {'font-size': 2}, {'font-size': 2.3}] 
styles = [a, b, c, a, a, a, c, a, a, b, b, c] 
# and now: 
c['font-size'] = 2 
the_values_immutable = [tuple(d.items()) for d in the_values] 
reduced = set(the_values_immutable) 
mapping = { itmtup: dict(itmtup) for itmtup in reduced } 
new_styles = [mapping[tuple(d.items())] for d in styles] 

这将创建代表每个字典元组的列表。然后通过设置算术来减少它。

结果是包含全新对象的样式列表。

如果你喜欢有一些保留任何原因,旧的项目,你最好更换

mapping = { itmtup: dict(itmtup) for itmtup in reduced } 

的东西看起来了每个项目的老the_values列表。

如果您必须经常这样做,并且希望尽可能多地减少它,则应该添加一个间接级别。

在这种情况下见falsetru's answer

+0

这是否比使用编辑:我认为你的编辑(“一层间接......”)和他的回答是一样的,如果我理解正确的话,在这种情况下,请看我对他的回答的第一个评论。 – Jeff

+0

@Jeff这取决于你多久这样做,如果你有两个具有相同内容的对象,它真的会受伤吗?也许你应该坚持一个每个文本区域在概念上都是相同的,如果两个样式在物理上是相同的,它们保持合法的方式,并且在需要时可以再次一起更改 – glglgl

0

由于c是一个容器,您可以清空它,然后将其中的项目从b复制到它。这可能会少于潜在更改styles中的10,000个条目的工作。

a,b,c = {'font-size':1},{'font-size':2},{'font-size':2.3} 
styles = [a,b,c,a,a,a,a,a,b,] 

c.clear() 
for k in b: 
    c[k] = b[k] 

print styles 

输出:

[{'font-size': 1}, {'font-size': 2}, {'font-size': 2}, {'font-size': 1}, 
{'font-size': 1}, {'font-size': 1}, {'font-size': 1}, {'font-size': 1}, 
{'font-size': 2}] 
+0

因为我会做很多很多次大的物体,正如我所说的,我在寻找为了节约内存,我不想让大量的容器完全相同。此外,这是一个解决方法,我很欣赏,但它并没有真正回答这个问题。 – Jeff

+0

我知道它不回答你的问题,是一种解决方法。但是,它不会创造更多的容器 - 现在只有三个容器。它只是改变了其中一个的内容。 – martineau

+0

对不起,我忘了添加上下文。你是对的,但我有更多更大的容器,并且不断创建新的容器(例如){font-size:3},然后将它们更改为font-size:2,再次创建一个新副本同样的事情。它也发生在我身上,我经常只想改变字体大小的一些*:2到3,所以我不能只是替换内容。 – Jeff

相关问题