【问题标题】:Python searching in nested lists to find values and insert values into a new listPython 在嵌套列表中搜索以查找值并将值插入新列表
【发布时间】:2017-11-08 15:34:21
【问题描述】:

我无法弄清楚如何搜索我拥有的嵌套列表以找到某些值,以便将不同的值添加到另一个嵌套列表中,如果这有意义的话?我将在下面尝试解释。

list1 = [[P1, 3, P2, 1],[P3, 2, P4, 1][P5, 3, P6, 2]]

基本上,这个嵌套列表表示玩家之间游戏的回合得分(P1 对 P2 得 3 分,P2 对 P1 得 1 分)。

我还有第二个嵌套列表:

list2 = [[P1], [P2], [P3], [P4], [P5], [P6]]

第二个嵌套列表将代表玩家之间的排名分数。我想要实现的是根据第一个嵌套列表中的玩家得分将排名得分插入到第二个嵌套列表中。例如,在“list1”中,P1、P3 和 P5 赢得了他们的回合,因此我想在“list2”中为这些玩家插入“5”(用于演示的任意数字)的排名分数,为其他玩家插入“0”播放器,以便列表看起来像这样:

list2 = [[P1, 5], [P2, 0], [P3, 5], [P4, 0], [P5, 5], [P6, 0]]

我正在努力弄清楚如何做到这一点背后的逻辑,所以任何帮助都将不胜感激

谢谢,

【问题讨论】:

  • 您可能会发现dicts 很有用,因为您可以直接使用玩家名称作为键。然后遍历您的第一个列表并比较分数并给您字典中的玩家 5 分。 :)
  • 如果我可以建议 - 我会使用列表以外的其他东西来跟踪排名 - 列表在达到一定大小时非常好,但与dict相比,它们最终会在性能上有所下降,例如。
  • 平局或复赛怎么样?
  • 您还缺少[P3, 2, P4, 1][P5, 3, P6, 2]] 之间的逗号

标签: python search insert compare nested-lists


【解决方案1】:

你可以试试这个:

P1 = "Team1"
P2 = "Team2"
P3 = "Team3"
P4 = "Team4"
P5 = "Team5"
P6 = "Team6"
n = 5
import itertools
list1 = [[P1, 3, P2, 1],[P3, 2, P4, 1], [P5, 3, P6, 2]]
final_data = list(itertools.chain(*[[[t1, n], [t2, 0]] if s1 > s2 else [[t1, 0], [t2, n]] for t1, s1, t2, s2 in list1]))

输出:

[['Team1', 5], ['Team2', 0], ['Team3', 5], ['Team4', 0], ['Team5', 5], ['Team6', 0]]

【讨论】:

  • 我喜欢你对 itertools 的使用,但是在复赛或平局的情况下你的答案会中断
【解决方案2】:

使用dict,您可以尝试类似

list1 = [["P1", 3, "P2", 1],["P3", 2, "P4", 1],["P5", 3, "P6", 2]]
playerDict = {"P1":0,"P2":0,"P3":0,"P4":0,"P5":0,"P6":0}

for entry in list1:
    if entry[1] > entry[3]:
        playerDict[entry[0]] = 5
    else:
        playerDict[entry[2]] = 5

playerDict 的输出:

{'P1': 5, 'P3': 5, 'P6': 0, 'P2': 0, 'P5': 5, 'P4': 0}

如果你喜欢https://www.tutorialspoint.com/python/python_dictionary.htm,还有更多信息给你:)

【讨论】:

  • 嘿,非常感谢这个例子,这是一个巨大的帮助,我真的很感激它,我会尝试使用字典来解决问题:D
  • 这会在重赛时中断
【解决方案3】:

对于您的第一次比较,假设格式保持如下:

list1 = [[P1, 3, P2, 1],[P3, 2, P4, 1][P5, 3, P6, 2]]

你可以做的最基本的比较是:

for score_list in list1:
    # score_list[1] and score_list[3] are the scores
    if score_list[1] > score_list[3]:
        # winner is player in score_list[0]
        winner = score_list[0]
        loser = score_list[2]
    elif score_list[1] < score_list[3]:
        winner = score_list[2]
        loser = score_list[0]
    else:
        # what do you do in case of a tie?
        pass

    # now do something with the winner information
    # if we're keeping list2 format, you'd have to scan
    # the list until you find the one where the first element
    # is the winner, and also do something for the loser
    for player_list in list2:
        if player_list[0] == winner:
            player_list.append(5)
        if player_list[0] == loser:
            player_list.append(0)

您可以改用字典来改进list2 处理,它可以让您将键映射到值。

players = {
    'P1': [],
    'P2': [],
    'P3': [],
     # ...and so on...
}

scores = [[P1, 3, P2, 1],[P3, 2, P4, 1],[P5, 3, P6, 2]]

for score in scores:
    if score_list[1] > score_list[3]:
        # winner is player in score_list[0]
        winner = score_list[0]
        loser = score_list[2]
    elif score_list[1] < score_list[3]:
        winner = score_list[2]
        loser = score_list[0]
    else:
        # what do you do in case of a tie?
        pass

    players[winner].append(5)
    players[loser].append(0)

【讨论】:

  • 嘿,我真的很感谢这个例子,它对理解它背后的逻辑有很大的帮助:DI 认为我现在可以尝试使用字典来完成它,就像你自己和其他人指出的那样,如果它是一个更多有效的方法。再次感谢:)
【解决方案4】:

另一个不那么优雅但实用的解决方案是这样的:

list1 = [['P1', 3, 'P2', 1],['P3', 2, 'P4', 1],['P5', 3, 'P6', 2]]
list2 = []

def takeScore(list1, list2, number):
    for i in list1:
        if i[1] > i[3]:
            list2.extend(([i[0],number],[i[2],0]))
        else:
            list2.extend(([i[1],0],[i[2],number]))

takeScore(list1,list2,5)
print(list2)

结果是:

[['P1', 5], ['P2', 0], ['P3', 5], ['P4', 0], ['P5', 5], ['P6', 0]]

【讨论】:

    【解决方案5】:

    根据您的问题,我的猜测是列表不是任意嵌套的,您实际上并没有搜索值,而是想将嵌套列表转换为另一种形式。

    但是,进一步考虑您的示例,我的猜测是,玩家可能有重复的比赛,因此可能赢得不止一场比赛?我的猜测是,其中一场比赛可能会出现平局。

    在任何一种情况下,查找逻辑都非常昂贵,我建议使用字典来计算点数。在那里,您可以简单地查找玩家名称P1, P2, ... 并增加存储在那里的点数。

    在这种情况下,您可以遍历所有匹配项,随时解压缩嵌套列表并比较点。根据比较结果,您可以相应地更新玩家字典:

    list1 = [["P1", 3, "P2", 1], ["P3", 2, "P4", 1], ["P5", 3, "P6", 2]]
    player_points = {}
    for player_1_name, player_1_points, player_2_name, player_2_points in list1:
        if player_1_points > player_2_points:
            player_1_points = 5
            player_2_points = 0
        elif player_1_points < player_2_points:
            player_1_ponints = 0
            player_2_points = 5
        else:    # Player 1 and 2 are tied
            player_1_points = 2
            player_2_points = 2
        if player_1_name not in player_points:
            player_points[player_1_name] = 0
        if player_2_name not in player_points:
            player_points[player_2_name] = 0
        player_points[player_1_name] += player_1_points
        player_points[player_2_name] += player_2_points
    

    运行后,字典如下所示:

    {'P2': 0, 'P3': 5, 'P1': 5, 'P6': 0, 'P4': 0, 'P5': 5}
    

    如果你真的想要一个元组列表,你可以将字典转换成这样的列表:

    list2 = list(player_points.items())
    

    输出:

    [('P2', 0), ('P3', 5), ('P1', 5), ('P6', 0), ('P4', 0), ('P5', 5)]
    

    如果你真的还需要里面的列表,这可以解决问题:

    list2 = [list(item) for item in player_points.items()]
    

    输出:

    [['P2', 0], ['P3', 5], ['P1', 5], ['P6', 0], ['P4', 0], ['P5', 5]]
    

    你甚至可以通过输入sorted来按玩家姓名排序:

    list2 = [list(item) for item in sorted(player_points.items())]
    

    输出:

    [['P1', 5], ['P2', 0], ['P3', 5], ['P4', 0], ['P5', 5], ['P6', 0]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多