on writing a while loop for rolling two dice

dn PythonList at DancesWithMice.info
Sat Sep 11 01:24:47 EDT 2021


On 31/08/2021 01.50, Chris Angelico wrote:
> On Mon, Aug 30, 2021 at 11:13 PM David Raymond <David.Raymond at tomtom.com> wrote:
>>
>>> def how_many_times():
>>>   x, y = 0, 1
>>>   c = 0
>>>   while x != y:
>>>     c = c + 1
>>>     x, y = roll()
>>>   return c, (x, y)
>>
>> Since I haven't seen it used in answers yet, here's another option using our new walrus operator
>>
>> def how_many_times():
>>     roll_count = 1
>>     while (rolls := roll())[0] != rolls[1]:
>>         roll_count += 1
>>     return (roll_count, rolls)
>>
> 
> Since we're creating solutions that use features in completely
> unnecessary ways, here's a version that uses collections.Counter:
> 
> def how_many_times():
>     return next((count, rolls) for count, rolls in
> enumerate(iter(roll, None)) if len(Counter(rolls)) == 1)
> 
> Do I get bonus points for it being a one-liner that doesn't fit in
> eighty characters?


Herewith my claim to one-liner fame (assuming such leads in any way to
virtue or fame)

It retains @Peter's preference for a more re-usable roll_die() which
returns a single event, cf the OP's roll() which returns two results).


import itertools, random

def roll_die():
    while True:
        yield random.randrange(1, 7)

def how_many_times():
    return list( itertools.takewhile( lambda r:r[ 0 ] != r[ 1 ],
                                      zip( roll_die(), roll_die() )
                                      )
               )

Also, a claim for 'bonus points' because the one-liner will fit within
80-characters - if only I didn't have that pernicious and vile habit of
coding a more readable layout.

It doesn't use a two-arg iter, but still rates because it does use a
relatively-obscure member of the itertools library...


https://docs.python.org/3.8/library/itertools.html#itertools.takewhile
-- 
Regards,
=dn


More information about the Python-list mailing list