python - 函数在无意时修改输入

标签 python python-3.x

我有 3 个列表:

years = [2013,2014,2015,2016,2017,2018]    
GamsVars = ['scen_name','timefile']
settings = ['ScenarioA','s']

我有一个函数,旨在返回一个与设置完全相同的列表,但在相关条目后附加了年份:

def AppendYearToSettings(year,GamsVarsIn,SettingsIn):
    SettingsOut = SettingsIn
    SettingsOut[GamsVarsIn.index('scen_name')] = SettingsIn[GamsVarsIn.index('scen_name')] + "\\" + str(year)
    SettingsOut[GamsVarsIn.index('timefile')] = SettingsIn[GamsVarsIn.index('timefile')] + str(year)
    return(SettingsOut)

当我在循环中测试该函数时:

for y in years:
    ysettings = AppendYearToSettings(y,GamsVars,settings)
    print(ysettings)

我的ysettings正在累计追加年份:

['ScenarioA\\2013', 's2013']
['ScenarioA\\2013\\2014', 's20132014']
['ScenarioA\\2013\\2014\\2015', 's201320142015']
['ScenarioA\\2013\\2014\\2015\\2016', 's2013201420152016']
['ScenarioA\\2013\\2014\\2015\\2016\\2017', 's20132014201520162017']
['ScenarioA\\2013\\2014\\2015\\2016\\2017\\2018', 's201320142015201620172018']

我已尝试明确阻止设置(原始设置)被修改,但似乎我的函数正在以某种方式修改设置。

导致此问题的原因是什么?

最佳答案

What is the reason that is causing this problem?

当您执行SettingsOut = SettingsIn时,您只是创建对SettingsIn引用的对象的另一个引用。如果您想复制该列表,可以执行以下操作:

SettingsOut = SettingsIn[:]

或者,您可以使用copy.deepcopy (您需要导入copy才能使用它)。仅当列表的元素本身是引用并且您还想创建对象的新副本时才需要此操作。看看下面 John Y 的评论。

SettingsOut = copy.deepcopy(SettingsIn)

看看这个:

>>> l1 = [1, 2, 3, 4, 5]
>>> l2 = l1
>>> l2 is l1
True
>>> id(l1)
24640248
>>> id(l2)
24640248

>>> l2 = l1[:]
>>> l2 is l1
False
>>> id(l2)
24880432
>>> id(l1)
24640248
>>>
<小时/>

所以你的函数可能是这样的:

def AppendYearToSettings(year,GamsVarsIn,SettingsIn):
    SettingsOut = SettingsIn[:]
    SettingsOut[GamsVarsIn.index('scen_name')] = SettingsIn[GamsVarsIn.index('scen_name')] + "\\" + str(year)
    SettingsOut[GamsVarsIn.index('timefile')] = SettingsIn[GamsVarsIn.index('timefile')] + str(year)
    return SettingsOut

for y in years:
    ysettings = AppendYearToSettings(y, GamsVars, settings)
    print(ysettings)

输出:

['ScenarioA\\2013', 's2013']
['ScenarioA\\2014', 's2014']
['ScenarioA\\2015', 's2015']
['ScenarioA\\2016', 's2016']
['ScenarioA\\2017', 's2017']
['ScenarioA\\2018', 's2018']
<小时/>

有点误入歧途,但你应该看看 PEP style guide for function naming ;-) 它说:

Function Names

Function names should be lowercase, with words separated by underscores as necessary to improve readability.

mixedCase is allowed only in contexts where that's already the prevailing style (e.g. threading.py), to retain backwards compatibility.

关于python - 函数在无意时修改输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36774411/

相关文章:

python - 为什么 Python 解释器会在下一行显示语法错误?

python - 模块未找到错误: No module named 'unidecode' yet I have the module installed

python - Python 3.7中使用工厂函数生成注释类型时出现 “typing.ClassVar”问题

python - 根据字符串中的值将字符串列表转换为 pandas DataFrame

python - 替换编码无法识别的字符

python - Tkinter Checkbutton 不会在颜色更改后保留其复选标记

python - 为什么我不必在调用 Python 脚本之前添加 'python'?

python - 支持自动换行的 Canvas create_text() 版本?

python - 在 PySpark 中缓存用户和产品潜在特征以缩短预测时间

python - 全局优化: How to find same minimum more consistently?