已编辑。该示例现已完全可复制。
我陷入了一个我不应该陷入的问题,使用一种熟悉的模式。我生成一些随机数据,通过打印三个 distinct 行向我证明自己是随机的,将随机数据附加到列表中,然后-所得列表中的行都相同。
from random import randint
fields = [
{"foo": "bar"},
]
def some_randomizing_func(adict):
adict["number"] = randint(0, 1000)
return adict
rows = []
for ith in range(3):
row = [some_randomizing_func(field) for field in fields]
print("BEFORE ", row) # Proves they are unique at this point
rows.append(row) # Therefore each list in this list should also be unique
print("AFTER ", rows) # But they're not!
将其作为脚本运行即可:
BEFORE [{'foo': 'bar', 'number': 306}]
BEFORE [{'foo': 'bar', 'number': 943}]
BEFORE [{'foo': 'bar', 'number': 230}]
AFTER [
[{'foo': 'bar', 'number': 230}],
[{'foo': 'bar', 'number': 230}],
[{'foo': 'bar', 'number': 230}]
]
我已经尝试了所有可以想到的方法-使用带数字键的字典而不是列表,使用fields.copy()
,使用enumerate()
和计数器并分配给列表索引,但是问题仍然存在。在附加后,row
在第一个print()
期间如何证明自己是唯一的,而在第二个print()
以后又不再唯一的呢?
更新:可以通过将append()行更改为
来解决此问题 rows.append(copy.deepcopy(row))
但是我不明白为什么为什么可以解决此问题,并且感觉它正在解决实际问题。
答案 0 :(得分:0)
我相信您的函数class App extends React.Component {
//...
render() {
const { data } = this.state;
return (
<div>
<ChildComponent data={data} />
</div>
);
}
}
//for array, ex: data = ["first","name"];
class ChildComponent extends React.Component {
render() {
return (
<React.Fragment>
{this.props.data.map(item =>
<p>{item}</p>
)}
</React.Fragment>
);
}
}
//for object, ex: data = {id: 1, name: 'John'};
class ChildComponent extends React.Component {
render() {
const {data} = this.props;
return (
<React.Fragment>
<p>{data.id}</p>
<p>{data.name}</p>
</React.Fragment>
);
}
}
//for single value (string, int, etc), ex: data = "my name";
class ChildComponent extends React.Component {
render() {
return (
<React.Fragment>
<p>{this.props.data}</p>
</React.Fragment>
);
}
}
//to show object as a string (could be any object mentioned before)
class ChildComponent extends React.Component {
render() {
return (
<React.Fragment>
{JSON.stringify(this.props.data)}
</React.Fragment>
);
}
}
函数具有某种副作用,即返回的每个列表实际上都指向同一列表对象。
这是您应该调查的。
但是,作为一种快速解决方案,您可以使用some_randomizing_func
来拥有copy.deepcopy
的独立副本,这样可以避免任何副作用。
row
请注意,深层副本的缺点是它会增加RAM消耗。 您可能会找到更好的方法来解决此问题。
答案 1 :(得分:0)
感谢@rightleg和其他人的评论,这是关键要点:
“因此,在循环之后,尽管行都是不同的对象,但它们都包含 same 对象。”因此,可以通过在随机函数中复制字典来解决问题,而无需使用deepcopy()
:
def some_randomizing_func(somedict):
newdict = somedict.copy()
newdict["number"] = randint(0, 1000)
return newdict