【问题标题】:How to define a iterative function involving for loop where the iterator i,j,l.. are also used in the defined iterative function如何定义涉及 for 循环的迭代函数,其中迭代器 i,j,l.. 也用于定义的迭代函数
【发布时间】:2019-04-15 00:20:49
【问题描述】:

我正在尝试使用递归函数来简化“for-loops”下方的任何数量的循环,我可能必须根据要求运行程序。我可以在函数中不使用 i, j, k, l.... 来定义递归函数,但我不知道或者我很难使用 i,j k.. 来定义迭代函数。 . 如果有人可以帮助我的想象力,我会很高兴。

adjcent_spin_product_matrix = []
z_partial = 0
spin = [-1, 1]
for i in spin:
    for j in spin:
        for k in spin:
            for l in spin:
               for m in spin:
                   for o in spin:
                       for p in spin:
                           adjcent_spin_product_matrix = adjcent_spin_product_matrix + [i*j+ j*k+ k*l+ l*n+ m*o+ o*p]

【问题讨论】:

  • 我真的不明白这个。一方面,spin 是一个只有 2 个元素的列表,因此引用 spin[3] 等将使您的脚本崩溃并出现错误。尽管所有这些循环都定义了循环变量ip,但您只使用过ijk。如果您无法提供工作版本,或者我们无法理解您正在尝试做什么,那么没有人可以帮助您简化此代码。
  • 但现在这更没有意义了。为什么要多次迭代相同的值?
  • 我要解决的问题要求得到一个相邻自旋积的矩阵,最终函数需要使用 i, j, k... 来描述矩阵。因此,对于每个自旋对[-1, 1],都有一个 for 循环,for 循环的数量取决于格点的数量。
  • 它只是旋转,而不是旋转 [3] 等。我重新编辑了代码。基本上,我想将所有 for 循环压缩为一个递归函数,并且我还想使用每个 for 循环中的 i、j、k .... 来编写最终函数。所以,我想让你明白,i,j,k,l……在代码中起作用。
  • 正如其他人所说,您的问题不是有史以来最清楚的......我已经发布了一个答案,我相信它的当前版本是重点,但不是 100%(也不是 95% ;-) 确保这正是您所要求的。你能告诉我,它可以吗,还是我最好把它删除?谢谢

标签: python list function loops iterator


【解决方案1】:

我之前的回答是反对你未经编辑的帖子,所以这里有一个更新:

根据您提供的代码,很明显您必须至少具有ij 的循环。

单独评估该循环会给出以下列表: [1, -1, -1, 1]

现在,您编码中的每个后续嵌套循环仅复制此列表中的每个元素,然后从前一个循环添加数组(重复两次):

i、j 和 k 循环给出[1, 1, -1, -1, -1, -1, 1, 1] + [1, -1, -1, 1, 1, -1, -1, 1] = [2, 0, -2, 0, 0, -2, 0, 2]

i、j、k 和 l 循环给出[1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1] + [1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1] + [1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1] = [3, 1, -1, 1, -1, -3, -1, 1, 1, -1, -3, -1, 1, -1, 1, 3]

等等……

因此,您可以简单地尝试以下方法:

adjacent_spin_product_matrix = []
ij_result = [1, -1, -1, 1]

def calc_product(adjacent_spin_product_matrix, number_of_indices):
    if number_of_indices == 2:
        return ij_result
    else:
        number_of_duplicates = 2 ** (number_of_indices - 2)
        curr_array = []
        for elem in ij_result:
            for dup in range(number_of_duplicates):
                curr_array.append(elem)
        prev_array = calc_product(adjacent_spin_product_matrix, number_of_indices - 1)
        temp_array = []
        temp_array.extend(prev_array)
        temp_array.extend(prev_array)
        result = []
        for i, elem in enumerate(curr_array):
            result.append(elem + temp_array[i])

        return result

现在,您应该会发现:

print(calc_product([], 2))  # equivalent to i and j case
print(calc_product([], 3))  # equivalent to i, j, and k case
print(calc_product([], 4))  # equivalent to i, j, k, and l case
print(calc_product([], 5))  # equivalent to i, j, k, l, and m case
print(calc_product([], 6))  # equivalent to i, j, k, l, m, and o case
print(calc_product([], 7))  # equivalent to i, j, k, l, m, o, and p case

这些给出了预期的结果:

[1, -1, -1, 1]
[2, 0, -2, 0, 0, -2, 0, 2]
[3, 1, -1, 1, -1, -3, -1, 1, 1, -1, -3, -1, 1, -1, 1, 3]
[4, 2, 0, 2, 0, -2, 0, 2, 0, -2, -4, -2, 0, -2, 0, 2, 2, 0, -2, 0, -2, -4, -2, 0, 2, 0, -2, 0, 2, 0, 2, 4]
[5, 3, 1, 3, 1, -1, 1, 3, 1, -1, -3, -1, 1, -1, 1, 3, 1, -1, -3, -1, -3, -5, -3, -1, 1, -1, -3, -1, 1, -1, 1, 3, 3, 1, -1, 1, -1, -3, -1, 1, -1, -3, -5, -3, -1, -3, -1, 1, 3, 1, -1, 1, -1, -3, -1, 1, 3, 1, -1, 1, 3, 1, 3, 5]
[6, 4, 2, 4, 2, 0, 2, 4, 2, 0, -2, 0, 2, 0, 2, 4, 2, 0, -2, 0, -2, -4, -2, 0, 2, 0, -2, 0, 2, 0, 2, 4, 2, 0, -2, 0, -2, -4, -2, 0, -2, -4, -6, -4, -2, -4, -2, 0, 2, 0, -2, 0, -2, -4, -2, 0, 2, 0, -2, 0, 2, 0, 2, 4, 4, 2, 0, 2, 0, -2, 0, 2, 0, -2, -4, -2, 0, -2, 0, 2, 0, -2, -4, -2, -4, -6, -4, -2, 0, -2, -4, -2, 0, -2, 0, 2, 4, 2, 0, 2, 0, -2, 0, 2, 0, -2, -4, -2, 0, -2, 0, 2, 4, 2, 0, 2, 0, -2, 0, 2, 4, 2, 0, 2, 4, 2, 4, 6]

【讨论】:

  • “现在,您编码中的每个后续嵌套循环仅复制此列表中的每个元素,然后从前一个循环添加数组(重复两次)”您能否详细说明此语句?你是什​​么意思添加从前一个循环重复两次的数组?
  • 当然可以。如果您查看只有 2 个元素(i 和 j)的迭代的输出,它是 [1, -1, -1,1] 我为 3 元素迭代创建输出如下:1)创建一个数组通过复制前一个(2 元素)数组中的每个元素。这给了我 [1, 1, -1, -1, -1, -1, 1, 1]。 2) 通过将前一个(2 元素)数组连接到自身来创建另一个临时数组。这产生 [1, -1, -1, 1] + [1, -1, -1, 1] = [1, -1, -1, 1, 1, -1, -1, 1] 3) 添加将步骤 1 和 2 中的临时数组一起得到 [2, 0, -2, 0, 0, -2, 0, 2]。
  • 创建4元素数组的时候可以重复上面的: 1) 取[1, -1, -1, 1],每个元素重复4次:[1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1] 2) 取 [1, -1, -1, 1] 并重复每个元素两次:[1, 1, -1, -1, -1, -1, 1, 1] 3) 将第 2 步中的数组连接到自身:[1, 1, -1, -1, -1, -1、1、1、1、1、-1、-1、-1、-1、1、1]。 4) 将 [1, -1, -1,1] 自身连接 4 次:[1, -1, -1,1, 1, -1, -1,1, 1, -1, -1,1, 1, -1, -1,1] 5) 将 1、3 和 4 的数组相加: [3, 1, -1, 1, -1, -3, -1, 1, 1, -1, - 3, -1, 1, -1, 1, 3]
  • 该模式只是在每次后续迭代中重复。我希望这会有所帮助。
【解决方案2】:

不需要递归函数。

如果您使用itertools.product,您可以对每个索引数量使用一个循环;你也可以简化计算,使用sumzip

from itertools import product
...
spin_products = []
n = int(input('how many indices? '))
...
for indices in product([-1, 1], repeat=n):
    spin_products.append(sum(i*j for i, j in zip(indices, indices[1:])))

【讨论】:

  • 当然,包含list.append(...) 的循环通常可以更改为列表理解,这也不例外,... = [sum(i*j for i, j in zip(ix, ix[1:])) for ix in product((-1,1), repeat=n)]
  • zip(indices, indices[1:]) : 这是非常聪明的逻辑!!
  • 你是怎么想到的?如果你能引导我完成你的思考过程以得出那个逻辑,因为对我来说,我必须写下所有内容并查看模式以意识到可以做到这一点并不是很明显。
  • 模式识别可能吗? ①任何仅在最深层次上包含代码的嵌套循环都是一种暗示itertools.product的模式-您的情况特别简单,因为同一个可迭代对象重复了n次-并且②实际计算是对乘积的总和,因此@ 987654328@ 和 zip 这是 Python 创建值对的方式。
  • 而且,zip(a_list, a_list[1:]) 是从列表中获取连续对的惯用语。
【解决方案3】:

如果您不想使用递归函数来执行此操作,您可以使用stack。将循环的每一级推入堆栈,以便稍后弹出它们。

堆栈是大多数语言中的基本数据结构,因为它是存储函数调用上下文的一种非常自然的方式,它也是 Stack Overflow 名称的来源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 2018-05-13
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 2016-01-18
    相关资源
    最近更新 更多