难以理解代码片段的流程

trouble understanding the flow of the code snippet

我很难理解下面的代码。 它计算可用面额('coins')

的硬币赚取金额('n')的方法的数量
def change(n, coins_available, coins_so_far):
    if sum(coins_so_far) == n:
        yield coins_so_far
    elif sum(coins_so_far) > n:
        pass
    elif coins_available == []:
        pass
    else:
        for c in change(n, coins_available[:], coins_so_far+[coins_available[0]]):
            yield c
        for c in change(n, coins_available[1:], coins_so_far):
            yield c

n = 15
coins = [1, 5, 10, 25]

solutions = [s for s in change(n, coins, [])]
for s in solutions:
    print s

输出:

[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, 5]
[1, 1, 1, 1, 1, 5, 5]
[1, 1, 1, 1, 1, 10]
[5, 5, 5]
[5, 10]

我明白第一次迭代是如何导致 [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, 5] 我相信 'coins_so_far' 在 'coins_available' 持有 [5,10,25]

非常感谢任何帮助。谢谢

I don't understand how the [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] gets converted to [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5]

它在任何意义上都不是 "converted"。 change 函数正在返回一个列表,而您的打印语句正在使用列表理解来打印多个结果。

区别很明显,第一个硬币组合是所有便士 (1),而第二个组合包含一个五分硬币 (5),替换了五个便士。

英文:

How to determine the ways to make change(for n cents, using coins in
coins_available denominations, and which include a pile of coins_so_far):
    If the coins_so_far sum to n:
        That is the unique way to do it.
        (Because we've already added enough coins to the pile to make
        the desired amount of change.)
    Otherwise, if the coins_so_far sum to more than n:
        There are no ways to do it.
        (Because there's already too much in our pile; we can't fix
        this by adding more.)
    Otherwise, if there are no coins_available:
        There are no ways to do it.
    Otherwise:
        (To make change for the rest of the pile, we either *do* add
        at least one more of the smallest possible coin, or we *don't*.)
        Every way to make change(for n cents, using the same
        coins_available, and which includes the coins_so_far
        as well as the first of the coins_available):
            Is one of the ways to do it.
            (Try adding a coin of the smallest denomination to the pile,
            and then figure out all the ways to make up the rest of the
            change. This finds the ways that do add the small coin.)
        Every way to make change(for n cents, using all the
        coins_available except the first, and including the
        coins_so_far):
            Is also a way to do it.
            (Find the ways that don't add the smallest coin denomination,
            by excluding it from the denominations we'll consider, and
            using the same process.)

由于您自己跟踪程序有困难,所以在入口和出口处添加打印语句。在每种情况下,打印有用的变量。你能自己跟着这个吗?更好的是,您可以将这种做法应用到您自己的编码中吗?

def change(n, coins_available, coins_so_far):
    print "ENTER: n=", n, "\tavailable=", coins_available, "\t so far:", coins_so_far
    if sum(coins_so_far) == n:
        print "EXIT1: good solution", coins_so_far
        yield coins_so_far
    elif sum(coins_so_far) > n:
        print "EXIT2:", coins_so_far, "exceeded", n, ".  Back up."
        pass
    elif coins_available == []:
        print "EXIT3: out of coins"
        pass
    else:
        for c in change(n, coins_available[:], coins_so_far+[coins_available[0]]):
            print "EXIT4:", c
            yield c
        for c in change(n, coins_available[1:], coins_so_far):
            print "EXIT5:", c
            yield c

n = 15
coins = [1, 5, 10, 25]

solutions = [s for s in change(n, coins, [])]
for s in solutions:
    print s