我正在尝试学习动态编程。我查看了一个示例,该示例如何查找输入n
的斐波那契数,同时在我进行操作时缓存每个“新”调用的结果。
我了解函数递归调用的顺序:fib(5)-> fib(4)-> fib(3)-> fib(2)-> fib(1)-> fib(0)-> fib(1)-> fib(2)“找到缓存”-> fib(3)“找到缓存” n = 5
我正在努力了解最终的fib(2)和fib(3)调用如何访问更新后的缓存,因为每个调用仅返回一个整数,而不返回列表,并且我认为我没有声明为全局变量的列表。
我本来希望列表在代码中表现得像整数x,所以欢迎解释如何将值传递回。
代码:
def fib(n, cache, x):
print(n, cache)
print("x: ", x)
x += 1
if n == 0 or n == 1:
return n
if cache[n] == 0:
cache[n] = fib(n-1, cache, x) + fib(n-2, cache, x)
else:
print("Cache called on", n)
return cache[n]
def main():
n = 5
x = 0
cache = [0 for _ in range(n+1)]
print(fib(n, cache, x))
print(cache)
print("x: ", x)
if __name__ == "__main__":
main()
输出:
5 [0, 0, 0, 0, 0, 0]
x: 0
4 [0, 0, 0, 0, 0, 0]
x: 1
3 [0, 0, 0, 0, 0, 0]
x: 2
2 [0, 0, 0, 0, 0, 0]
x: 3
1 [0, 0, 0, 0, 0, 0]
x: 4
0 [0, 0, 0, 0, 0, 0]
x: 4
1 [0, 0, 1, 0, 0, 0]
x: 3
2 [0, 0, 1, 2, 0, 0]
x: 2
Cache called on 2
3 [0, 0, 1, 2, 3, 0]
x: 1
Cache called on 3
5
[0, 0, 1, 2, 3, 5]
x: 0
答案 0 :(得分:1)
您传递了cache
的原件,而不是副本(新建对象)。因此,fib
的每个实例都与 same 对象一起工作。一个实例中的更新立即可供其他实例使用。另请参见here。
答案 1 :(得分:1)
在python函数中,参数是“对象传递”(或对象引用传递)。这意味着,如果将列表(可变对象)传递给函数,则可以修改列表的元素。但是,如果您要通过新列表分配列表,则该列表在调用者的范围内不会更改。
public static void convertToExcel(string fileName, string splitter, string extension)
{
string newFileName = fileName.Replace("." + extension, ".xls");
string[] lines = File.ReadAllLines(fileName, Encoding.UTF8);
int columnCounter = 0;
foreach (string s in lines)
{
string[] ss = s.Trim().Split(Convert.ToChar(splitter));
if (ss.Length > columnCounter)
columnCounter = ss.Length;
}
HSSFWorkbook workbook = new HSSFWorkbook();
var sheet = workbook.CreateSheet("Data");
var rowIndex = 0;
var rowExcel = sheet.CreateRow(rowIndex);
foreach (string s in lines)
{
rowExcel = sheet.CreateRow(rowIndex);
string[] ss = s.Trim().Split(Convert.ToChar(splitter));
for (int i = 0; i < columnCounter; i++)
{
string data = !String.IsNullOrEmpty("s") && i < ss.Length ? ss[i] : "";
rowExcel.CreateCell(i).SetCellType(CellType.String);
rowExcel.CreateCell(i).SetCellValue(data);
}
rowIndex++;
}
for (var i = 0; i < sheet.GetRow(0).LastCellNum; i++)
sheet.AutoSizeColumn(i);
using (FileStream file = new FileStream(newFileName, FileMode.Create, FileAccess.Write))
{
workbook.Write(file);
file.Close();
}
}
输出:
def list_scope(l):
print(l, "id: ", id(l))
l = [3, 4,5]
print(l, "id: ", id(l))
def main():
l = [1, 2, 3]
print("id: ", id(l))
list_scope(l)
print("id: ", id(l))
main()
在分配列表id: 4510275784
[1, 2, 3] id: 4510275784
[3, 4, 5] id: 4509275592
id: 4510275784
之前l
中list_scope
的ID与[3, 4, 5]
中的ID相同。一旦分配了main
,它就会更改,但在[3, 4, 5]
中保持不变。