python-3.x 卡在这个功能上

3lxsmp7m  于 2023-04-13  发布在  Python
关注(0)|答案(1)|浏览(108)
def moves_to_nested_dict(moves: list[list[str]]) -> dict[tuple[str, int], dict]:
    """
    Convert <games> into a nested dictionary representing the sequence of moves
    made in the games.

    Each list in <games> corresponds to one game, with the i'th str being the
    i'th move of the game.

    The nested dictionary's keys are tuples containing the string representing
    the move made on that turn and an integer indicating how many games ended
    immediately after this move. See the docstring example below.

    The values of each nested dictionary are themselves nested dictionaries of
    this structure. An empty dictionary is stored as the value for a move that
    will correspond to a leaf

    Note: to keep the docstring short, we use single letters in place
          of real chess moves, as it has no impact on the logic of how this
          code needs to be implemented, since it should work for arbitary
          strings used to denote moves.

    >>> moves_to_nested_dict([[]])  # empty lists are ignored
    {}
    >>> moves_to_nested_dict([])
    {}
    >>> moves_to_nested_dict([['a'], []])
    {('a', 1): {}}
    >>> d = moves_to_nested_dict([["a", "b", "c"],
    ...                           ["a", "b"], ["d", "e"], ["d", "e"]])
    >>> d
    {('a', 0): {('b', 1): {('c', 1): {}}}, ('d', 0): {('e', 2): {}}}
    >>> d = moves_to_nested_dict([
    ...    ["a", "b", "c"], ["a", "b"], ["d", "e", "a"], ["d", "e"]])
    >>> d
    {('a', 0): {('b', 1): {('c', 1): {}}}, ('d', 0): {('e', 1): {('a', 1): {}}}}
    """

我一直在尝试解决这个函数,但我有点卡住了。我知道如何写一般结构,但不知道如何正确地得到数字。有人可以帮助实现吗
这就是我所做的

result = {}
for game_moves in moves:
    if len(game_moves) == 0:
        continue
    current_dict = result
    num_ended_games = 0
    for move in game_moves[:-1]:
        key = (move, num_ended_games)
        if key not in current_dict:
            current_dict[key] = {}
        current_dict = current_dict[key]
        num_ended_games = 0
    last_move = game_moves[-1]
    key = (last_move, num_ended_games)
    if key not in current_dict:
        current_dict[key] = {}
    current_dict = current_dict[key]
    num_ended_games += 1
return result

错误消息为

失败示例:d
预期:

{('a', 0): {('b', 1): {('c', 1): {}}}, ('d', 0): {('e', 2): {}}}

得到:

{('a', 0): {('b', 0): {('c', 0): {}}}, ('d', 0): {('e', 0): {}}}
9nvpjoqh

9nvpjoqh1#

你在嵌套for循环上走对了路,但是

num_ended_games = 0 ## beginning of loop
key = (move, num_ended_games)
        if key not in current_dict:
num_ended_games += 1 ## end of loop

在循环结束时递增num_ended_games而不在任何地方设置它不会在result字典中更新它。要change a dictionary key,您需要将旧值设置为新键,并将del.pop设置为旧键。此外,请记住,元组在Python中不是可变的,因此要更改元组中的一个值,您需要替换整个元组...
尝试类似下面的moves_to_nested_dict版本。(view example outputs

def moves_to_nested_dict(moves: list[list[str]]) -> dict[tuple[str,int], dict]:
    result = {}
    for game_moves in moves:
        cur_dict = result

        for reverse_index, move in enumerate(game_moves, 1-len(game_moves)):
            cur_key = [k for k in cur_dict if k[0]==move]            
            if not cur_key: cur_dict[(cur_key := (move, 0))] = {}
            else: cur_key = cur_key[0]
            
            if not reverse_index: ## <-- reverse_index=0 on last move
                cur_dict[(move, cur_key[1]+1)] = cur_dict.pop(cur_key)
            else: cur_dict = cur_dict[cur_key]
    return result

[将enumeratestart=1-len一起使用,使reverse_index1-len开始计数,并以0结束-因此我们可以使用它来跟踪还剩多少步以及何时走到最后一步;而walrus操作符(:=)只是一种在一个语句中定义/更新和使用变量的方便方法,而不需要在使用它之前首先设置它。
顺便说一句,如果num_ended_games是字典 * 内部 * 的一个值,那么这将简单得多,这样只有move可以用作键,并且您可以只使用.setdefault,而不需要检查和有时更新键:

def moves_to_nested_dict(moves: list[list[str]]) -> dict[str,dict]:
    result = {}
    for game in moves:
        cur_dict = result
        for move in game: 
            cur_dict = cur_dict.setdefault(move, {'__games_ended__':0}) # (move,{})
        if game: cur_dict['__games_ended__'] = cur_dict.get('__games_ended__',0)+1
    return result

[当您无法确定密钥是否存在时,使用<dict>.get(<key>)比使用<dict>[<key>]更安全。]
有了这个版本,

moves_to_nested_dict([['a','b'], ['a','b'], ['a','b','c'], ['d','a'], ['a','d']])

将返回

{
  'a': {
    '__games_ended__': 0,
    'b': {'__games_ended__': 2, 'c': {'__games_ended__': 1}},
    'd': {'__games_ended__': 1}
  },
  'd': {'__games_ended__': 0, 'a': {'__games_ended__': 1}}
}

相关问题