函数调用和函数中的代码给出不同的结果

2024-10-03 21:27:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我的程序中有一个bug,我正在尝试使用Pycharm的debug工具和evaluate expression进行调试。我发现了我的代码不起作用的原因,但不明白这样的事情是怎么发生的。当我用一些参数调用我的函数边际化transition时,结果是1.0,但是当我在该函数中运行代码并用参数替换它们时,结果是0.00101001196095。但是,它们应该是相同的,因为它是相同的代码。
player = 1world.amountOfPlayers() = 2world.amountOfPossibleActions = 5。你知道吗

marginalizedTransitionTest(Ps, [(3, 1), (5, 1)], [(2, 1), (5, 1)], 0, world, 1)

在哪里

def marginalizedTransitionTest(Ps, sis, sfs, action, world, player):
    otherPlayers = filter(lambda x: x != player, range(world.amountOfPlayers()))
    return sum(np.prod([Ps[otherPlayer][tuple(it.chain(*sis))]
                   [np.insert(actions, player, action)[otherPlayer]]
                   for otherPlayer in otherPlayers])
           for actions in it.product(range(world.amountOfPossibleActions), repeat=world.amountOfPlayers() - 1))

给出4.05514478458和

sum(np.prod([Ps[otherPlayer][tuple(it.chain(*[(3, 1), (5, 1)]))]
               [np.insert(actions, 1, 0)[otherPlayer]]
               for otherPlayer in filter(lambda x: x != 1, range(world.amountOfPlayers()))])
       for actions in it.product(range(world.amountOfPossibleActions), repeat=world.amountOfPlayers() - 1))

给出1.0。你知道吗

我不知道这是不是一个常见的问题。如果你需要更多关于所用函数的信息,我可以提供,但是这个帖子已经很难看了。你知道吗


Tags: 函数代码inactionsforworld参数np
1条回答
网友
1楼 · 发布于 2024-10-03 21:27:49

这是由于filter作为迭代器的行为造成的。在函数中,首先创建迭代器,然后对它运行for多次。但是,如果您尝试运行以下命令:

otherPlayers = filter(lambda x: x != player, range(world.amountOfPlayers()))
for player in otherPlayers:
    print(f'1: {player}')
for player in otherPlayers:
    print(f'2: {player}')

结果将是:

1: 0
1: 1

如您所见,一旦您在过滤器上运行了for,它将用尽,并且不会返回任何内容。
您在原始运行时没有执行相同的操作,因此迭代器按预期工作。
因此,解决方法很简单:在for中添加过滤器:

def marginalizedTransition(Ps, sis, sfs, action, world, player):
    return sum(world.joinedTransition(sis, sfs, np.insert(actions, player, action)) *
               np.prod([Ps[otherPlayer][tuple(it.chain(*sis))][np.insert(actions, player, action)[otherPlayer]]
                        for otherPlayer in filter(lambda x: x != player, range(world.amountOfPlayers()))])
               for actions in it.product(range(world.amountOfPossibleActions), repeat=world.amountOfPlayers() - 1))

或者,正如您在chat中指出的,您可以将迭代器转换为一个列表:

def marginalizedTransition(Ps, sis, sfs, action, world, player):
    otherPlayers = list(filter(lambda x: x != player, range(world.amountOfPlayers())))
    return sum(world.joinedTransition(sis, sfs, np.insert(actions, player, action)) *
               np.prod([Ps[otherPlayer][tuple(it.chain(*sis))][np.insert(actions, player, action)[otherPlayer]]
                        for otherPlayer in otherPlayers])
               for actions in it.product(range(world.amountOfPossibleActions), repeat=world.amountOfPlayers() - 1))

对于那些想要重现这个问题的用户,我基于聊天讨论创建了这些虚拟对象,并像这样解构了理解:

import numpy as np
import itertools as it


class World:
    amountOfPossibleActions = 5

    def amountOfPlayers(self):
        return 2

    def joinedTransition(self, a, b, insert):
        return 1 if insert[0] == 3 else 0


world = World()
player = 1

Ps = {0: {(3, 1, 5, 1): [[0.055144784579474179], [0.055144784579474179], [0.055144784579474179], [0.055144784579474179],
                         [0.055144784579474179]]}}


def marginalizedTransition(Ps, sis, sfs, action, world, player):
    otherPlayers = filter(lambda x: x != player, range(world.amountOfPlayers()))
    s = 0
    for actions in it.product(range(world.amountOfPossibleActions), repeat=world.amountOfPlayers() - 1):
        w = world.joinedTransition(sis, sfs, np.insert(actions, player, action))
        a = []
        for otherPlayer in otherPlayers:
            b = np.insert(actions, player, action)[otherPlayer]
            v = Ps[otherPlayer][tuple(it.chain(*sis))][b]
            a.append(v)
        p = np.prod(a)
        s += w * p
    return s

就个人而言:列表理解非常好,它使代码非常紧凑。但是,这会使读取和调试代码变得非常困难。下次你想了解的时候请记住这一点。我只能找出什么是错的,解构后,它如上所示。你知道吗

相关问题 更多 >