简体   繁体   中英

Python: Getting a list from **args to run in a for loop

I'm trying to run a function that takes a list of player ranks that creates a dictionary (game_on) that has values that are above the average rank of that game should the game be fair (which I have set up in another function). I'm having trouble understanding why when I run Line 15 that I cannot run the list that I accessed in the for loop

def is_fair_game(*player_ranks):
    for args in player_ranks:
        if len(player_ranks) == 0:
            return False
        if len(player_ranks) % 2 == 0:
            highest = max(player_ranks)
            lowest = min(player_ranks)
            return highest-lowest <= 5
        else:
            return False

def matchmaking(**games):
    game_on = {}
    for g, args in games.items():
        if is_fair_game(args[0:len(args)]) == False:
            game_on[g] = 'not a fair game'
        if is_fair_game(args) == True:
            for i in args:
                if i >= mean(args):
                    game_on[g].append[i]
        if len(game_on[g]) == 0:
            game_on[g] = 'not a fair game'
    return game_on

matchmaking(game_1=[50, 49, 51, 52], game_2=[71, 73, 71, 71], game_3=[18, 23, 22, 18])

The list of Game One doesn't run through my is_fair_game function

  1. args[0:len(args)] is always the same thing as args (in your instance - since you aren't modifying args ), and much less readable - change that to just args .
  2. Your for loop in is_fair_game is useless, as args is never used.
  3. To unpack a list into many positional arguments, eg is_fair_game([1, 2, 3]) becomes is_fair_game(1, 2, 3) , use the * symbol. So your code becomes: is_fair_game(*args) . **However I do not recommend writing is_fair_game to take a variable number of arguments. The benefit of using a list as an argument is that it can be any length, so why bother unpacking it in the first place? Especially since in your code a list would be sufficient.
  4. Evaluate booleans directly, don't compare them to False or True . So if is_fair_game(*args) == False: becomes if not is_fair_game(*args):

I've made a few changes in your code, and is now running by the rules you wanted to implement (if I interpreted them correctly).

I removed the loop in the is_fair_game function, given it was both not looping (it always stopped in the first element) and it was not necessary as well. I removed the * in is_fair_game(*player_ranks) as suggested by Blckknght.

Down the road, you compute an average, so I imported numpy to compute it.

import numpy as np

def is_fair_game(player_ranks):

    if len(player_ranks) == 0:
        return False
    if len(player_ranks) % 2 == 0:
        highest = max(player_ranks)
        lowest = min(player_ranks)
        return highest-lowest <= 5
    else:
        return False

def matchmaking(**games):
    game_on = {}
    #insert the keys in the dictionary, and an empty list
    for g in games:
        game_on[g] = []
    for g, args in games.items():
        if is_fair_game(args[:]) == False:
            game_on[g] = 'not a fair game'
        if is_fair_game(args):
            for i in args:
                if i >= np.mean(args):
                    game_on[g].append(i)
        if len(game_on[g]) == 0:
            game_on[g] = 'not a fair game'
    return game_on

matchmaking(game_1=[50, 49, 51, 52], game_2=[71, 73, 71, 71], game_3=[18, 23, 22, 18])

There were some other mistakes that I corrected, but you can check on the code itself. Hopefully this works out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM