简体   繁体   English

对于循环,如何在循环外使用循环变量

[英]For loop, how can i use loop variable outside loop

LR = int(raw_input()) 
RPL = []
c1 = []
c2 = []
L1a = [8, 9, 14, 13, 12]
L2a =[9, 12, 14, 10, 8]
OM = [9, 10]
L3a = [26]
L1b = [27, 32, 26]
L2b = [30, 27, 32, 28, 31]
L3b = [31, 30, 26]

def I():
    for i in L1b:
        for j in L2b:
            for k in L3b:
                n = i * j * k
                c1.append(n)
    for i in OM:
        for j in L1a:
            for k in L2a:
                n = i * j * k
                c2.append(n)
def II():
    for i in c1:
        for j in c2:
            x = (i / j) * LR
            RPL.append(x)

In my program I need for loop variables i,j,k from 'I' function to print them in my 'II' function to show what combination was used to create x. 在我的程序中,我需要从“ I”函数获取循环变量i,j,k,以便在“ II”函数中打印它们,以显示用于创建x的组合。 I tried with two dimensional arrays but it didnt work well. 我尝试了二维数组,但效果不佳。 So is there any easy option to work this out? 那么有什么简单的选择可以解决这个问题吗?

The following script I think does what you are trying to do: 我认为以下脚本可以完成您想做的事情:

import operator, itertools

LR = int(raw_input())

L1a = [8, 9, 14, 13, 12]
L2a = [9, 12, 14, 10, 8]
L3a = [26]
L1b = [27, 32, 26]
L2b = [30, 27, 32, 28, 31]
L3b = [31, 30, 26]
OM = [9, 10]

c1 = [(reduce(operator.mul, p), p) for p in itertools.product(L1b, L2b, L3b)]
c2 = [(reduce(operator.mul, p), p) for p in itertools.product(OM, L1a, L2a)]

RPL = [(((p[0][0]) / p[1][0]) * LR, p[0][1], p[1][1])  for p in itertools.product(c1, c2)]

print RPL

This displays the following type of results of an LR of 10 : 这将显示LR10的以下结果类型:

[(380, (27, 30, 31), (9, 8, 9)), (290, (27, 30, 31), (9, 8, 12)), (240, (27, 30, 31), (9, 8, 14)), ... etc

Each permutation is stored as a tuple with the result of the multiplication. 每个置换都存储为具有乘法结果的元组。 This is then used when calculating your RPL value. 然后在计算您的RPL值时使用它。

You could also format RPL as follows, to show which permutations made each result: 您还可以按如下所示设置RPL格式,以显示产生每个结果的排列:

for rpl, p1, p2 in RPL:
    print "%8d  %15s  %15s" % (rpl, str(p1), str(p2))

Giving output in the form: 以以下形式提供输出:

 380     (27, 30, 31)        (9, 8, 9)
 290     (27, 30, 31)       (9, 8, 12)
 240     (27, 30, 31)       (9, 8, 14)
 340     (27, 30, 31)       (9, 8, 10)
 430     (27, 30, 31)        (9, 8, 8)
 340     (27, 30, 31)        (9, 9, 9)

The script uses the Python itertools module. 该脚本使用Python itertools模块。 This provides a product function which has the same effect of having multiple nested for loops. 这提供了product函数,具有与嵌套多个for循环相同的效果。 The result of each iteration gives your values for i , j and k , but as a tuple, eg (27, 30, 31) . 每次迭代的结果给出ijk ,但以元组的形式给出,例如(27, 30, 31)

The reduce command can be used to multiply all of the numbers in the list that was returned, by applying the same function to each entry. 通过对每个条目应用相同的函数, reduce命令可用于将返回的列表中的所有数字相乘。 As you can't write reduce( * , p) , you can use Python's operator module to provide a function name version for * , ie operator.mul . 由于无法编写reduce( * , p) ,因此可以使用Python的operator模块为*提供函数名称版本,即operator.mul

The result of this gets wrapped in () to make a tuple with two parts, the first is the result of the multiplications and the second part is the permutation that produced it. 其结果包装在()以组成具有两个部分的元组,第一部分是乘法的结果,第二部分是产生它的置换。 eg (25110, (27, 30, 31)) . 例如(25110, (27, 30, 31))

c1 is a list holding all of these value. c1是包含所有这些值的列表。 This is called a list comprehension. 这称为列表理解。 It is equivalent to a for loop with c1.append() inside. 它等效于内部带有c1.append()for循环。

Once c1 and c2 have been created (I suggest you try and print their values to see what they look like), the script then uses a similar method to calculate all of the RPL values. 一旦创建了c1c2 (我建议您尝试打印它们的值以查看它们的外观),然后脚本将使用类似的方法来计算所有RPL值。 Each iteration gives p which would look like: 每次迭代都给出p ,它看起来像:

((25110, (27, 30, 31)), (648, (9, 8, 9)))

This is a tuple with two entries (25110, (27, 30, 31)) and (648, (9, 8, 9)) . 这是具有两个条目(25110, (27, 30, 31))(648, (9, 8, 9)) Python can access each value using indexes. Python可以使用索引访问每个值。 So to get the 25110 you would use p[0][0] for the first tuple, first part. 因此,要获得25110您可以将p[0][0]用于第一元组,第一部分。 Or p[0][1] to get (27, 30, 31) . p[0][1]得到(27, 30, 31)

The solution script could be converted to not use list comprehensions as follows: 解决方案脚本可以转换为不使用列表推导,如下所示:

c1 = []

for p in itertools.product(L1b, L2b, L3b):
    multiply_all = reduce(operator.mul, p)
    c1.append((multiply_all, p))

c2 = []

for p in itertools.product(OM, L1a, L2a):
    multiply_all = reduce(operator.mul, p)
    c2.append((multiply_all, p))

RPL = []

for p in itertools.product(c1, c2):
    calculation = (p[0][0] / p[1][0]) * LR
    RPL.append((calculation, p[0][1], p[1][1]))

If you want i, j and k, store them instead of their product. 如果要i,j和k,请存储它们而不是产品。 Instead of c1.append(n) , use c1.append((i, j, k)) . 代替c1.append(n) ,使用c1.append((i, j, k))

Then, in II would look like this: 然后,在II中将如下所示:

for (i1, j1, k1) in c1:
    for (i2, j2, k2) in c2:
        i = i1 * j1 * k1
        j = i2 * j2 * k2

        x = (i / j) * LR
        RPL.append(x)

A thing you should consider is that you can return two lists from I instead of having two global lists. 您应该考虑的事情是,您可以从I返回两个列表,而不是拥有两个全局列表。 Global variables that are modified are usually a Bad Thing. 被修改的全局变量通常是一件坏事。

You can't use loop variables outside the loop. 您不能在循环外使用循环变量。 Never. 决不。 Even if language allows that - it is totally confusing and a sign of a bad code structure. 即使语言允许,也完全是令人困惑的,并且是不良代码结构的迹象。

Regarding your question - there are a number of ways to do that. 关于您的问题-有多种方法可以做到这一点。 The least involving would be to use a tuple instead of a number in last iteration of I (do you have a better names for them?). 涉及最少的是在I最后一次迭代中使用元组而不是数字(您有更好的名字吗?)。

def I():
    # snip
    n = i * j * k
    c2.append((i, j, k, n))  # double braces is important

def II():
    # snip
    for c1_loop_var in c1:  # note loop variable name changed
        for i, j, k, n in c2:
            x = (c1_loop_var / n) * LR
            # and whatever you need to do with i,j,k

As a side note, the snippet you provided does not contain a single variable with a good name, so it's totally not clear to anyone. 附带说明一下,您提供的代码段不包含一个具有好名字的变量,因此任何人都不清楚。 If you're going to be the only user of this code - up to you, but I would try giving them more sensible names - it's a good practice anyway. 如果您将成为该代码的唯一用户-由您决定,但我会尝试给他们提供更明智的名称-无论如何,这都是一个好习惯。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM