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 = generate_rounds(n=1_000_000) # a generator
iwinner = map(RPS_winner_star, irounds)
score_board = Counter(iwinner)
Here is a full example and timings:
(Note: the generate_rounds generator is now predictably repetitive in an effort to reduce its own time in the overall measurements; we also now subtract the time spent in the generator in the time comparisons at the end).
import random
from collections import Counter
from itertools import starmap
def generate_rounds(n):
choices = list('RPS')
m = len(choices)
for k in range(n):
i = k % m
j = (k // m) % m
yield choices[i], choices[j]
def f_onlygen(n):
for _ in generate_rounds(n):
pass
def f_map(n):
irounds = generate_rounds(n) # a generator
iwinner = map(RPS_winner_star, irounds)
return Counter(iwinner)
def f_starmap(n):
irounds = generate_rounds(n) # a generator
iwinner = starmap(RPS_winner, irounds)
return Counter(iwinner)
def f_listmap(n):
rounds = list(generate_rounds(n))
winner = list(map(RPS_winner_star, rounds))
return Counter(winner)
def f_listcomprehension(n):
rounds = list(generate_rounds(n))
winner = [RPS_winner(a, b) for a, b in rounds]
return Counter(winner)
def f_comprehension(n):
irounds = generate_rounds(n)
winner = [RPS_winner(a, b) for a, b in rounds]
return Counter(winner)
Measurements:
n = 1_000_000
t = {}
t['onlygen'] = %timeit -o f_onlygen(n)
t['map'] = %timeit -o f_map(n)
t['starmap'] = %timeit -o f_starmap(n)
t['listmap'] = %timeit -o f_listmap(n)
t['listcomprehension'] = %timeit -o f_listcomprehension(n)
t['comprehension'] = %timeit -o f_comprehension(n)
Results:
res = sorted([
(k, v.average, v.average - t['onlygen'].average)
for k, v in t.items()
], key=lambda tup: tup[2])
print(f'{"name":<17} {"total":<6} above onlygen')
for name, tot, rel in res:
print(f'{name:<17} {tot*1000:3.0f} ms, {rel*1000:3.0f} ms')
name total above onlygen
onlygen 172 ms, 0 ms
comprehension 235 ms, 62 ms
starmap 376 ms, 204 ms
map 432 ms, 260 ms
listcomprehension 470 ms, 298 ms
listmap 482 ms, 310 ms