好的,这是我正在使用的完整代码。现在我提供了输入和输出。希望早些时候我的荒谬问题更有意义......
def get_positions(xs, item):
if isinstance(xs, list):
for i, it in enumerate(xs):
for pos in get_positions(it, item):
yield (i,) + pos
elif xs == item:
yield ()
blocks = [-12,-10,-8,-6,-4,-2,0,2,4,6,8,10,12,14,16]
startcombos = [[-12], [-12, -10], [-12, -10, -8], [-12, -10, -8, -6], [-12, -10, -8, -6, -4], [-12, -10,-8, -6, -4, -2], [-12, -10, -8, -6, -4, -2, 0], [-12, -10, -8, -6, -4, -2, 0, 2], [-12, -10, -8, -6, -4, -2, 0, 2, 4], [-12, -10, -8, -6, -4, -2, 0, 2, 4, 6], [-12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8], [-12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10], [-12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12], [-12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14], [-12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16]]
combos = [[-10], [-10, -8], [-10, -8, -6], [-10, -8, -6, -4], [-10, -8, -6, -4, -2], [-10, -8, -6,-4, -2, 0], [-10, -8, -6, -4, -2, 0, 2], [-10, -8, -6, -4, -2, 0, 2, 4], [-10, -8, -6, -4, -2, 0, 2, 4, 6], [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8], [-10, -8, -6, -4, -2, 0, 2, 4, 6,8, 10], [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12], [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14], [-10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16], [-8], [-8, -6], [-8, -6, -4], [-8, -6, -4, -2], [-8, -6, -4, -2, 0], [-8, -6, -4, -2, 0, 2], [-8, -6, -4, -2, 0, 2, 4], [-8, -6, -4, -2, 0, 2, 4, 6], [-8, -6, -4, -2, 0, 2, 4, 6, 8], [-8, -6, -4, -2, 0, 2, 4, 6, 8, 10], [-8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12], [-8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14], [-8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16], [-6], [-6, -4], [-6, -4, -2], [-6, -4, -2, 0], [-6, -4, -2, 0, 2], [-6, -4, -2, 0, 2, 4], [-6, -4, -2, 0, 2, 4, 6], [-6, -4, -2, 0, 2, 4, 6, 8], [-6, -4, -2, 0, 2, 4, 6, 8, 10], [-6, -4, -2, 0, 2, 4, 6, 8, 10, 12], [-6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14], [-6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16], [-4], [-4, -2], [-4, -2, 0], [-4, -2, 0, 2], [-4, -2, 0, 2, 4], [-4, -2, 0, 2, 4, 6],[-4, -2, 0, 2, 4, 6, 8], [-4, -2, 0, 2, 4, 6, 8, 10], [-4, -2, 0, 2, 4, 6, 8, 10, 12], [-4, -2, 0, 2, 4, 6, 8, 10, 12, 14], [-4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16], [-2], [-2, 0],[-2, 0, 2], [-2, 0, 2, 4], [-2, 0, 2, 4, 6], [-2, 0, 2, 4, 6, 8], [-2, 0, 2, 4, 6, 8, 10], [-2, 0, 2, 4, 6, 8, 10, 12], [-2, 0, 2, 4, 6, 8, 10, 12, 14], [-2, 0, 2, 4, 6, 8, 10, 12, 14, 16], [0], [0, 2], [0, 2, 4], [0, 2, 4, 6], [0, 2, 4, 6, 8], [0, 2, 4, 6, 8, 10], [0,2, 4, 6, 8, 10, 12], [0, 2, 4, 6, 8, 10, 12, 14], [0, 2, 4, 6, 8, 10, 12, 14, 16], [2], [2, 4], [2, 4, 6], [2, 4, 6, 8], [2, 4, 6, 8, 10], [2, 4, 6, 8, 10, 12], [2, 4, 6, 8, 10, 12, 14], [2, 4, 6, 8, 10, 12, 14, 16], [4], [4, 6], [4, 6, 8], [4, 6, 8, 10], [4, 6, 8, 10,12], [4, 6, 8, 10, 12, 14], [4, 6, 8, 10, 12, 14, 16], [6], [6, 8], [6, 8, 10], [6, 8, 10, 12], [6, 8, 10, 12, 14], [6, 8, 10, 12, 14, 16], [8], [8, 10], [8, 10, 12], [8, 10, 12, 14], [8, 10, 12, 14, 16], [10], [10, 12], [10, 12, 14], [10, 12, 14, 16], [12], [12, 14], [12, 14, 16], [14], [14, 16], [16]]
temp = []
for i in range(len(startcombos)):
for j in list(get_positions(combos,startcombos[i][-1]+2)):
if j[-1]==0 and combos[j[0]][-1]!=blocks[-1]:
for k in list(get_positions(combos,combos[j[0]][-1]+2)):
if k[-1]==0 and combos[k[0]][-1]!=blocks[-1]:
for l in list(get_positions(combos,combos[k[0]][-1]+2)):
if l[-1]==0 and combos[l[0]][-1]==blocks[-1]:
temp.append(tuple(startcombos[i]))
temp.append(tuple(combos[j[0]]))
temp.append(tuple(combos[k[0]]))
temp.append(tuple(combos[l[0]]))
combinations.append(temp)
temp = []
这是一个生成长度为4的temp的代码。如果组合的长度增加,我会在更大的循环中包含另一个条件,如下所示
for i in range(len(startcombos)):
for j in list(get_positions(combos,startcombos[i][-1]+2)):
if j[-1]==0 and combos[j[0]][-1]!=blocks[-1]:
for k in list(get_positions(combos,combos[j[0]][-1]+2)):
if k[-1]==0 and combos[k[0]][-1]!=blocks[-1]:
for l in list(get_positions(combos,combos[k[0]][-1]+2)):
if l[-1]==0 and combos[l[0]][-1]!=blocks[-1]:
for m in list(get_positions(combos,combos[l[0]][-1]+2)):
if m[-1]==0 and combos[m[0]][-1]==blocks[-1]:
temp.append(tuple(startcombos[i]))
temp.append(tuple(combos[j[0]]))
temp.append(tuple(combos[k[0]]))
temp.append(tuple(combos[l[0]]))
temp.append(tuple(combos[m[0]]))
combinations.append(temp)
temp = []
这将生成长度为5的临时值。正如您已注意到第一个和最后一个条件和循环更改,中间部分保持不变。如何编写一个函数或任何其他方法,我可以用可变长度来实现它?
现在我得到的基本上是通过提供特定条件获得的组合。我知道我可以尝试使用itertools的python组合,但如果我想要特定的组合,那么生成所有组合根本不值得,除了计算时间也很重要。因此,它将为长度4提供以下输出
combinations[0] = [[-12],[-10],[-8],[-6,-4,-2,0,2,4,6,8,10,12,14,16]]
等等,其中364个。
对于长度为5,它将总共提供1001种组合,其中第一种是
combinations[0] = [[-12],[-10],[-8],[-6],[-4,-2,0,2,4,6,8,10,12,14,16]]
答案 0 :(得分:2)
我不完全确定我是否正确解释了你的问题;然而,接下来是一个相当普遍的练习,无论是哪种方式都应该能够启发你。出于讨论的目的,我假设您的目标是执行任意数量的嵌套for循环。
首先,让我满足Pythonistas读这个,说Pythonic这样做的方法可能涉及使用函数itertools.product和可能内置的filter()
函数。
除此之外,我认为你应该熟悉递归的概念,因为它允许你“天真地”对这类问题提出简单的解决方案,而不必依赖于像Python这样的甜蜜语言为你提供了一个充满生成器功能的强大库。
假设您在某些列表列表中有一些列表,例如:
nested = [[a1, a2, a3, ..., ana],
[b1, b2, b3, ..., bnb],
...
[x1, x2, x3, ..., xnx]]
并且您希望通过包含每个列表中的单个元素的序列迭代伪词法,例如:
a1 b1 c1 ... x1
a1 b1 c1 ... x2
...
a2 b1 c1 ... x1
a2 b1 c1 ... x2
...
...
ana bnb cnc ... x(nx - 1)
ana bnb cnc ... xnx
使用普通的静态for循环很难做到这一点,因为你通常必须输出每个,对吗?你如何键入一些可变数量的for循环?一种天真的技巧是使用递归(同样这不是最恐怖的方式)。
递归说,“好吧,我有一个问题。这个问题基本上只是用我的部分数据做一些小事,然后 递归 解决同样的问题其余的数据。当我没有更多的数据可用时,我可能已经完成了这个子问题。“
一个简单,经典的递归示例是计算数字列表的总和:
def sum_nums(nums):
# The "base case" is usually checked first. This is when your
# recursion has run out of things to do, it just returns a simple value.
if nums == []:
return 0
# The "recursive case" is the real meat and potatoes of recursion.
# It says to take the first number and add it to the sum_nums of the
# rest of the numbers in the list (which may be empty, hence the base case!).
else:
return nums[0] + sum_nums(nums[1:])
想一想。明白它。冥想它,忘记你理解它。做一些迷幻药,再考虑一下。能够在飞行中从你的屁股中拉出递归的黑客是非常重要的。
现在更先进的技术是在递归函数中传递值。在这种情况下,它可能很有用,因为在您了解基本情况之前,您不想做任何事情。如果你愿意的话,我已经遗漏了你自己实施的基础案例。
def print_lexo_lists(items, lists):
if lists == []:
# What do you want to do if you've taken a single item from each of your
# lists and put it in the list called "items"?
else:
# Take each item from the current level and pass it down in turn to the
# next deeper level, adding it to the running list of "items". Remove
# the current level from the list of "lists" before passing it down.
# In this way you're "using up" the current level, and the "lists"
# structure is getting smaller at each level of recursive depth, until
# you reach the base case (when it is an empty list)
for current_item in lists[0]:
print_lexo_lists(items + [current_item], lists[1:])
希望你能在某种程度上遵循这一点。我强烈建议您在尝试以下方法之前实现它,这实际上是通过生成 笛卡尔积来在Python中执行超级嵌套for循环的正确方式> 列表:
from itertools import product
for items in product(*lists):
print ' '.join(items)