Append 不断追加相同的项目,没有追加正确的项目,Python

Append keeps on appending the same item, does not append the right ones, Python

这是我导入的:

import random
import matplotlib.pyplot as plt
from math import log, e, ceil, floor
import numpy as np
from numpy import arange,array
import pdb
from random import randint

这里我定义函数matrix(p,m)

def matrix(p,m):            # A matrix with zeros everywhere, except in every entry in the middle of the row
    v = [0]*m
    v[(m+1)/2 - 1] = 1
    vv = array([v,]*p)
    return vv

ct = np.zeros(5)            # Here, I choose 5 cause I wanted to work with an example, but should be p in general  

这里我定义了 MHops,它基本上采用矩阵、矩阵和向量 ct 的维度,并给我一个新矩阵 mm 和一个新向量 ct

def MHops(p,m,mm,ct):

k = 0
while k < p :                 # This 'spans' the rows
    i = 0
    while i < m :             # This 'spans' the columns
        if mm[k][i] == 0 :
            i+=1
        else:
            R = random.random()
            t = -log(1-R,e)              # Calculate time of the hopping
            ct[k] =  ct[k] + t
            r = random.random()
            if  0 <= r < 0.5 :              # particle hops right
                if 0 <= i < m-1:
                    mm[k][i] = 0
                    mm[k][i+1] = 1
                    break
                else: 
                    break           # Because it is at the boundary
            else:                            # particle hops left 
                if 0 < i <=m-1:    
                    mm[k][i] = 0
                    mm[k][i-1] = 1
                    break
                else:              # Because it is at the boundary
                    break
            break
    k+=1    
return (mm,ct)               # Gives me the new matrix showing the new position of the particles and a new vector of times, showing the times taken by each particle to hop

现在我想做的是迭代这个过程,但我希望能够可视化列表中的每一步。简而言之,我正在做的是: 1. 创建一个表示格子的矩阵,其中 0 表示该槽中没有粒子,1 表示该槽中有一个粒子。 2. 创建一个函数 MHops 来模拟一步的随机游走,并给我新的矩阵和一个向量 ct,它显示粒子移动的时间。

现在我想要一个向量或数组,其中我有 2*n 个对象,即矩阵 mm 和向量 ct 进行 n 次迭代。我想要数组、列表或类似的东西,因为我以后需要使用它们。

我的问题从这里开始:

我创建了一个空列表,我使用 append 在 while 循环的每次迭代中追加项目。然而,我得到的结果是一个列表 d,其中包含来自上次迭代的 n 个相等对象!

因此我的迭代函数如下:

def rep_MHops(n,p,m,mm,ct):
    mat = mm
    cct = ct
    d = []
    i = 0
    while i < n :
        y = MHops(p,m,mat,cct)       # Calculate the hop, so y is a tuple y = (mm,ct)
        mat = y[0]                 # I reset mat and cct so that for the next iteration, I go further
        cct = y[1]
        d.append(mat)
        d.append(cct)
        i+=1
    return d


z = rep_MHops(3,5,5,matrix(5,5),ct)      #If you check this, it doesn't work
print z

然而它不起作用,我不明白为什么。我正在做的是使用 MHops,然后我想将新矩阵和新向量设置为 MHops 输出中的那些,然后再次执行此操作。但是,如果您 运行 这段代码,您会看到 v 有效,即时间的向量增加并且点阵矩阵发生变化,但是当我将其附加到 d 时,d 基本上是 n 个相等对象的列表,其中对象是最后一次迭代。

我的错误是什么? 此外,如果您对此代码有任何编码建议,我们将非常欢迎,我不确定这是一种有效的方法。

为了让你更好地理解,我想在另一个函数中使用最终向量 d,首先我选择一个随机时间 T,然后我基本上会检查每个奇数条目(每个 ct),然后检查每个ct的每个条目,看看这些数字是否小于或等于T。如果发生这种情况,那么粒子的运动就发生了,否则就没有发生。 然后我将尝试使用 matpotlibt 将结果可视化为直方图或类似的东西。

有谁知道如何在matlab中运行进行这种模拟吗?你认为它会更容易吗?

You're passing and storing by references not copies, so on the next iteration of your loop MHops alters your previously stored version in d. Use import copy; d.append(copy.deepcopy(mat)) to instead store a copy which won't be altered later.

为什么?

Python 通过引用传递列表,并且每个循环都在 d.

中存储对 same 矩阵对象的引用

我查看了 python 文档,我唯一能找到的是 "how do i write a function with output parameters (call by reference)".

这是一个更简单的代码示例:

def rep_MHops(mat_init):
    mat = mat_init
    d = []
    for i in range(5):
        mat = MHops(mat)
        d.append(mat)
    return d


def MHops(mat):
    mat[0] += 1
    return mat

mat_init = [10]
z = rep_MHops(mat_init)
print(z)

当运行给出:

[[15], [15], [15], [15], [15]]

Python 仅通过引用传递 可变对象 (例如列表)。整数不是可变对象,这里是对单个整数进行操作的上述示例的略微修改版本:

def rep_MHops_simple(mat_init):
    mat = mat_init
    d = []
    for i in range(5):
        mat = MHops_simple(mat)
        d.append(mat)
    return d


def MHops_simple(mat):
    mat += 1
    return mat

z = rep_MHops_simple(mat_init=10)
print(z)

当运行给出:

[11, 12, 13, 14, 15]

这是您所期望的行为。

这个 SO 答案 How do I pass a variable by reference? 解释得很好。