简体   繁体   中英

python map over list of tuples

I have list of tuples like this:

rounds = [('R', 'S'), ('S', 'R'), ('S', 'R'), ('R', 'P'), ('S', 'S'),
          ('P', 'S'), ('P', 'S'), ('S', 'P'), ('R', 'R'), ('R', 'S')]

that are simulating RPS game also i have a function like this:

def RPS_winner(weapon1, weapon2):
  if weapon1 == weapon2:
    return 0
  elif (weapon1, weapon2) in [('R', 'S'), ('P', 'S'), ('P', 'S')]:
    return 1
  else:
    return 2

how do i use map() to derive a list of the winners in those 10 rounds? i know is starting like this: list(map(RPS_winner, ....)

Itertools provides starmap for this.

from itertools import starmap

rounds = [('R', 'S'), ('S', 'R'), ('S', 'R'), ('R', 'P'), ('S', 'S'),
          ('P', 'S'), ('P', 'S'), ('S', 'P'), ('R', 'R'), ('R', 'S')]

def RPS_winner(weapon1, weapon2):
    if weapon1 == weapon2:
        return 0
    elif (weapon1, weapon2) in [('R', 'S'), ('P', 'S'), ('P', 'S')]:
        return 1
    else:
        return 2

    
list(starmap(RPS_winner, rounds))
# [1, 2, 2, 2, 0, 1, 1, 2, 0, 1]

You don't need map for something like that, and in fact would gain readability by using a list comprehension:

>>> [RPS_winner(a, b) for a, b in rounds]
[1, 2, 2, 2, 0, 1, 1, 2, 0, 1]

Another possibility is to use itertools.starmap , which is designed precisely for that:

from itertools import starmap

list(starmap(RPS_winner, rounds))

And, of course, you can do the same by hand:

list(map(lambda ab: RPS_winner(*ab), rounds)

which, if you intend to use on very long list of rounds , would benefit being rewritten as:

def RPS_winner_star(ab):
    return RPS_winner(*ab)

list(map(RPS_winner_star, rounds))

Note

A justifiable reason to request the use of map or the like is that rounds is in fact not a list but another iterator. In that case, it's nice to obtain a new iterator that spits out winners as rounds go, without making lists. For example, you could then "pipe" that resulting iterator into a Counter :

irounds = simulate_rounds(n=1_000_000)  # a generator
iwinner = map(RPS_winner_star, rounds)
score_board = Counter(iwinner)

You can do this:

winners = list(map(lambda x: RPS_winner(*x), rounds))

starting like this: list(map(RPS_winner, ....)

If it shall start like that, it should probably end like this:

list(map(RPS_winner, *zip(*rounds)))

That gives map three arguments: The function, player 1 choices, player 2 choices.

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