Python 如何将嵌套的 For 循环放入函数中?
Python How Can I Put Nested For Loops Into a Function?
我正在编写一个 python 脚本,其中我有多个 for 循环,除了其中嵌套的 for 循环的数量外,它们都是相同的。
让我告诉你我的意思:
#4 & 1
for a1 in someList:
for a2 in someList:
for a3 in someList:
for a4 in someList:
for b1 in anotherList:
resultList.append((a1 + a2 + a3 + a4) - b1);
#3 & 1
for a1 in someList:
for a2 in someList:
for a3 in someList:
for b1 in anotherList:
resultList.append((a1 + a2 + a3) - b1);
#2 & 1
for a1 in someList:
for a2 in someList:
for b1 in anotherList:
resultList.append((a1 + a2) - b1);
#2 & 2
for a1 in someList:
for a2 in someList:
for b1 in anotherList:
for b2 in anotherList:
resultList.append((a1 + a2) - (b1 + b2));
请记住,这只是一个演示问题的示例。我正在处理的实际数据不是数字,而且每次迭代我都执行了很多操作。
好了,下面是问题:
如何将所有这些代码放入一个漂亮的函数中,以便我可以做这样的事情:
myFunc(4, 1);
myFunc(3, 1);
myFunc(2, 1);
myFunc(2, 2);
如果你们能回答这个问题,这将对我有很大的帮助。我没有足够的创造力独自解决这个难题。 :(
此外,如果答案已经存在,我很抱歉发布这个问题 -- 我不知道这个东西叫什么,所以我不知道要搜索什么。
提前致谢!
~下午
更新:
谢谢大家的帮助。我认为这会奏效。你们都非常有帮助!
我的方法是首先否定您的 b
列表。这样,您可以使用类似的东西:
from itertools import product
def sum_of_cartesian_tuples(*lists):
tuples = product(*lists)
return map(sum, tuples)
if __name__ == '__main__':
a1 = [1,2,3]
a2 = [3,4,5]
b1 = [6,7,8]
b1_neg = [-1*b for b in b1]
print sum_of_cartesian_tuples(a1, a2, b1_neg)
# [-2, -3, -4, -1, -2, ..., 0, -1, 2, 1, 0]
请注意,此代码在 Python 2.7 中,尚未在 Python 3.X 中进行测试。但是,本质上,您的循环遍历列表生成的笛卡尔积中的元组,因此使用 itertools.product
可以节省所有循环。
没问题。作为一个忠告,这么多嵌套的 for 循环是糟糕的风格,会让你的代码难以理解,甚至对你来说也是如此!您可能应该避免深度超过两个循环。如果其他东西需要循环,您可以为此编写一个函数。
itertools
(https://docs.python.org/3/library/itertools.html#itertools.product) 中实际上有一个函数可以满足您的需求,称为 product()
。 product
会给你一个可迭代对象的笛卡尔积,例如,如果 someList = [1, 2, 3 ... n]
那么 product(someList, 2)
会给你 [(1, 1), (1, 2), (1, 3) ... (1, n), (2, 1) ... (n, 1) ... (n, n)]
。您可以改变列表自身重复的次数。对 someList
和 someOtherList
都这样做
def func(num_a, num_b):
a_sums = sum(a_inner for a_inner in product(someList, repeat=num_a))
b_sums = sum(b_inner for b_inner in product(someOtherList, repeat=num_b))
return (a - b for a, b in product(a_sums, b_sums))
此函数将生成第一个列表的笛卡尔积之和的可迭代对象,然后对另一个列表执行相同的操作。请记住,您可能希望能够将列表作为参数传递,而不是将它们视为一些非局部变量。
您可以使用 itertools 生成笛卡尔积:
import itertools
> a = [1,2]
> b = [3,4]
> c = [4,5]
> itertools.product(a, b, c)
[(1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (2, 2, 4), (2, 2, 5), (2, 3, 4), (2, 3, 5)]
您可以使用循环或列表理解生成列表列表:
> list1 = [1,2,3]
> list2 = [3,4,5]
> a, b = 4, 1
> [list1 for i in range(a)] + [list2 for i in range(b)]
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [2, 3, 4]]
然后使用笛卡尔积:
> lists = [list1 for i in range(a)] + [list2 for i in range(b)]
> itertools.product(*lists)
您可以添加一个函数来处理每个子列表:
def doWorkOnProduct(list1, list2, a, b, func):
lists = [list1 for i in range(a)] + [list2 for i in range(b)]
products = itertools.product(*lists)
return map(func, products)
调用示例:
def func(nums):
return sum(nums[:-1]) + nums[-1]
> sums = list(doWorkOnProduct([1,2,3], [4,5,6], 4, 1, func))
> print sum(sums)
> 3159
我正在编写一个 python 脚本,其中我有多个 for 循环,除了其中嵌套的 for 循环的数量外,它们都是相同的。
让我告诉你我的意思:
#4 & 1
for a1 in someList:
for a2 in someList:
for a3 in someList:
for a4 in someList:
for b1 in anotherList:
resultList.append((a1 + a2 + a3 + a4) - b1);
#3 & 1
for a1 in someList:
for a2 in someList:
for a3 in someList:
for b1 in anotherList:
resultList.append((a1 + a2 + a3) - b1);
#2 & 1
for a1 in someList:
for a2 in someList:
for b1 in anotherList:
resultList.append((a1 + a2) - b1);
#2 & 2
for a1 in someList:
for a2 in someList:
for b1 in anotherList:
for b2 in anotherList:
resultList.append((a1 + a2) - (b1 + b2));
请记住,这只是一个演示问题的示例。我正在处理的实际数据不是数字,而且每次迭代我都执行了很多操作。
好了,下面是问题:
如何将所有这些代码放入一个漂亮的函数中,以便我可以做这样的事情:
myFunc(4, 1);
myFunc(3, 1);
myFunc(2, 1);
myFunc(2, 2);
如果你们能回答这个问题,这将对我有很大的帮助。我没有足够的创造力独自解决这个难题。 :(
此外,如果答案已经存在,我很抱歉发布这个问题 -- 我不知道这个东西叫什么,所以我不知道要搜索什么。
提前致谢! ~下午
更新: 谢谢大家的帮助。我认为这会奏效。你们都非常有帮助!
我的方法是首先否定您的 b
列表。这样,您可以使用类似的东西:
from itertools import product
def sum_of_cartesian_tuples(*lists):
tuples = product(*lists)
return map(sum, tuples)
if __name__ == '__main__':
a1 = [1,2,3]
a2 = [3,4,5]
b1 = [6,7,8]
b1_neg = [-1*b for b in b1]
print sum_of_cartesian_tuples(a1, a2, b1_neg)
# [-2, -3, -4, -1, -2, ..., 0, -1, 2, 1, 0]
请注意,此代码在 Python 2.7 中,尚未在 Python 3.X 中进行测试。但是,本质上,您的循环遍历列表生成的笛卡尔积中的元组,因此使用 itertools.product
可以节省所有循环。
没问题。作为一个忠告,这么多嵌套的 for 循环是糟糕的风格,会让你的代码难以理解,甚至对你来说也是如此!您可能应该避免深度超过两个循环。如果其他东西需要循环,您可以为此编写一个函数。
itertools
(https://docs.python.org/3/library/itertools.html#itertools.product) 中实际上有一个函数可以满足您的需求,称为 product()
。 product
会给你一个可迭代对象的笛卡尔积,例如,如果 someList = [1, 2, 3 ... n]
那么 product(someList, 2)
会给你 [(1, 1), (1, 2), (1, 3) ... (1, n), (2, 1) ... (n, 1) ... (n, n)]
。您可以改变列表自身重复的次数。对 someList
和 someOtherList
都这样做
def func(num_a, num_b):
a_sums = sum(a_inner for a_inner in product(someList, repeat=num_a))
b_sums = sum(b_inner for b_inner in product(someOtherList, repeat=num_b))
return (a - b for a, b in product(a_sums, b_sums))
此函数将生成第一个列表的笛卡尔积之和的可迭代对象,然后对另一个列表执行相同的操作。请记住,您可能希望能够将列表作为参数传递,而不是将它们视为一些非局部变量。
您可以使用 itertools 生成笛卡尔积:
import itertools
> a = [1,2]
> b = [3,4]
> c = [4,5]
> itertools.product(a, b, c)
[(1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (2, 2, 4), (2, 2, 5), (2, 3, 4), (2, 3, 5)]
您可以使用循环或列表理解生成列表列表:
> list1 = [1,2,3]
> list2 = [3,4,5]
> a, b = 4, 1
> [list1 for i in range(a)] + [list2 for i in range(b)]
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [2, 3, 4]]
然后使用笛卡尔积:
> lists = [list1 for i in range(a)] + [list2 for i in range(b)]
> itertools.product(*lists)
您可以添加一个函数来处理每个子列表:
def doWorkOnProduct(list1, list2, a, b, func):
lists = [list1 for i in range(a)] + [list2 for i in range(b)]
products = itertools.product(*lists)
return map(func, products)
调用示例:
def func(nums):
return sum(nums[:-1]) + nums[-1]
> sums = list(doWorkOnProduct([1,2,3], [4,5,6], 4, 1, func))
> print sum(sums)
> 3159