3

私は独学で Python を学んでおり、クリスマス プレゼントを交換するための小さなスクリプトを作成しました (これは宿題ではありません)。私の家族は、一人一人が同じ性別の人に一つずつ贈り物をするのが好きです. 次のスクリプトはほとんどの場合機能しますが、無限再帰によって失敗することがあります。基本的なケースは最終的に満たされると思うので、理由はわかりません。

import random

family = {'Joe': 'm', 'Jane': 'f', 'John': 'm', 'Jill': 'f', 'James': 'm', 'Jade': 'f'}
receivers = family.copy()
givers = family.copy()

def match(giver):
    index = random.randrange(len(receivers))
    giverGender = givers[giver]
    receiver = receivers.keys()[index]
    receiverGender = receivers.values()[index]

    if giver != receiver and giverGender == receiverGender:
        del receivers[receiver]
        return giver + ' to ' + receiver
    else:
        return match(giver)

# main program
for i in givers:
    print match(i)

これはエラーです(完全なエラーを追加するには編集してください):

Traceback (most recent call last):
  File "C:\...\christmasGifts.py", line 22, in <module>
    print match(i)
  File "C:\...\christmasGifts.py", line 18, in match
    return match(giver)

  ...

  File "C:\...\christmasGifts.py", line 18, in match
    return match(giver)
  File "C:\...\christmasGifts.py", line 9, in match
  index = random.randrange(len(receivers))
  File "C:\Python27\lib\random.py", line 184, in randrange
istart = int(start)
RuntimeError: maximum recursion depth exceeded while calling a Python object

助けてくれてありがとう。

4

5 に答える 5

6

まず、女性について考えてみましょう。プログラムが実行され、Jane と Jill が一致し、次に Jill と Jane が一致する場合、残る女性は Jane だけであり、彼女自身を一致させることができないため、プログラムは一致することなく無期限に実行されます。

あなたの問題を解決する別の方法を提案させてください。贈る側/受け取る側の順番をランダムにシャッフルし、各人がリストの次の人にギフトを贈り、リストの最後の人が最初の人にギフトを贈るようにします。それは次のようになります。

from random import shuffle
women = ['Jane', 'Jill', 'Jade']
shuffle(women)
print women[-1] + ' to ' + women[0]
for i in range(len(women) - 1):
    print women[i] + ' to ' + women[i+1]
于 2012-11-16T17:53:49.900 に答える
2

ジェーンとジル、ジルとジェーン

ジェイドは誰にあげる?

于 2012-11-16T17:53:31.927 に答える
0

これは、スクリプトの単純な反復バリアントです。それはかなりうまくいきます。

仮定として、確率論に基づいて、マッチ関数を何度も呼び出すだけで、プログラムが再帰制限に達することがあると思います

import random

family = {'Joe': 'm', 'Jane': 'f', 'John': 'm', 'Jill': 'f', 'James': 'm', 'Jade': 'f'}
receivers = family.copy()
givers = family.copy()

def match(giver):
    giverGender = givers[giver]

    Found = False
    while not Found:
        index = random.randrange(len(receivers))
        receiver = receivers.keys()[index]
        receiverGender = receivers.values()[index]
        if giver != receiver and giverGender == receiverGender:
            Found = True
            del receivers[receiver]
    return giver + ' to ' + receiver


# main program
if __name__=='__main__':
    for i in givers:
        print match(i)
于 2012-11-16T17:54:34.330 に答える
0

以下のバージョンでは、実際にはより多くの選択肢があります。

from random import randint

giver = ['Jane', 'Jill', 'Jade', 'Nicole', 'Charlotte']

receiver = [i for i in giver]

def match(giver, receiver):
    for i in giver:

        #get random receiver
        rec = receiver[randint(0,len(receiver)-1)]

        #check to see if only two remain, so person doesn't pick self in loop.
        if len(receiver) == 2:
            rec = receiver[1]

        #make sure person doesn't select themself.
        while i == rec:
            rec = receiver[randint(0,len(receiver)-1)]

        print i + " gives to " + rec
        #reduce receiver pool
        receiver.remove(rec)

編集:感謝祭で帽子から絵を描く楽しみが台無しになっていると思います.... :)

于 2012-11-16T20:17:02.660 に答える
0

これを行うには、少し理解しやすい方法があります。

from itertools import izip_longest
from random import shuffle

family = {
    'Joe': 'm',
    'Jane': 'f',
    'John': 'm',
    'Jill': 'f',
    'James': 'm',
    'Jade': 'f'
}

females = [k for k, v in family.iteritems() if v == 'f']
for num in range(5):
    shuffle(females) # muck up the order a bit
    print list(izip_longest(females, females[1:], fillvalue=females[0]))

[('Jade', 'Jill'), ('Jill', 'Jane'), ('Jane', 'Jade')]
[('Jane', 'Jill'), ('Jill', 'Jade'), ('Jade', 'Jane')]
[('Jade', 'Jane'), ('Jane', 'Jill'), ('Jill', 'Jade')]
[('Jade', 'Jane'), ('Jane', 'Jill'), ('Jill', 'Jade')]
[('Jill', 'Jane'), ('Jane', 'Jade'), ('Jade', 'Jill')]
于 2012-11-16T18:10:00.543 に答える