Próbuję stworzyć prosty program w Pythonie 3.3, który wykonuje listę czterech nazw i losowo przypisuje je do innej osoby na liście. Na przykład, jeśli nazwy były John, Aaron, Lydia i Robin:

John idzie pierwszy i wybiera nazwę. Nie może przyciągnąć własnych; Jeśli on to zrobi, wkłada go ponownie i ponownie rysuje. Powiedz, że John Drew Nazwisko Robina. Nazwa Robina zostanie wyeliminowana z basenu. Dalej jest kolej Aarona, aby rysować. Rysuje Johna. Imię Johna jest wyeliminowane. itd. Do momentu przypisania wszystkich nazw.

Stworzyłem listę z czterema nazwami i przypisałem każdą jedną wartość 1-4. Jednak prowadzę problem podczas wyjmowania z listy, mówiąc, że wartość nie istnieje.

List.Remove (x): X Nie na liście.

Wygląda mniej więcej tak:

def drawNames():
    import random
    John=1
    Aaron=2
    Lydia=3
    Robin=4
    validNames=[John, Aaron, Lydia, Robin]
    nameDrawn=random.choice(validNames)
    def draw():
        nameDrawn=random.choice(validNames)
    #John's Draw:
    draw()
    if nameDrawn != 1:
        if nameDrawn == 2:
            print("John drew: Aaron")
            validNames.remove(2)
        elif nameDrawn == 3:
            print("John drew: Lydia")
            validNames.remove(3)
        elif nameDrawn == 4:
            print("John drew: Robin")
            validNames.remove(4)
    #Aaron's Draw:
    draw()
    if nameDrawn !=2:
        if nameDrawn ==1:
            print("Aaron drew: John")
            validNames.remove(1)
        elif nameDrawn ==3:
            print("Aaron drew: Lydia")
            validNames.remove(3)
        elif nameDrawn ==4:
            print("Aaron drew: Robin")
            validNames.remove(4)
    #Lydia's Draw:
    draw()
    if nameDrawn !=3:
        if nameDrawn ==1:
            print("Lydia drew: John")
            validNames.remove(1)
        elif nameDrawn ==2:
            print("Lydia drew: Aaron")
            validNames.remove(2)
        elif nameDrawn ==4:
            print("Lydia drew: Robin")
            validNames.remove(4)
    #Robin's Draw:
    draw()
    if nameDrawn !=4:
        if nameDrawn ==1:
            print("Robin drew: John")
            validNames.remove(1)
        elif nameDrawn ==2:
            print("Robin drew: Aaron")
            validNames.remove(2)
        elif nameDrawn ==3:
            print("Robin drew: Lydia")
            validNames.remove(3)
drawNames()

Próbowałem również używać nazwisk, a nie wartości numerycznych, co dało ten sam błąd.

Czuję się również, że jest to nieefektywny schemat. Jeśli masz lepszą sugestię, byłbym bardzo zobowiązany.

3
CharlieTango92 7 grudzień 2013, 06:15

6 odpowiedzi

Najlepsza odpowiedź

Możesz mieć lepszy przebieg z poniższym kodem; Jest bardziej skalowalny dla wielu nazw niż to, co podałeś powyżej.

import copy
import random
validNames=["John", "Aaron", "Lydia", "Robin"]

def drawNames(namelist,currentname):
    '''
    namelist: list of names to draw from
    currentname: name of person doing the current draw
    '''
    draw_namelist = copy.copy(namelist) # make a copy to remove person drawing if needed
    if currentname in draw_namelist: # check if the person drawing is in the list
        draw_namelist.remove(currentname) # remove current name if in list
    try:
        drawn_name = random.choice(draw_namelist)
        namelist.remove(drawn_name)
        newnamelist = namelist
        print "Drew {}".format(drawn_name)
        print "New list: {}".format(newnamelist)
    except:
        print "Nobody for me to draw!"
        drawn_name=None
        newnamelist = namelist
    return drawn_name, newnamelist

Może to następnie działać w następujący sposób:

In [39]: newlist=["John", "Aaron", "Lydia", "Robin"]

In [40]: name,newlist = drawNames(newlist,"Lydia")
Drew Robin
New list: ['John', 'Aaron', 'Lydia']

In [41]: name,newlist = drawNames(newlist,"John")
Drew Aaron
New list: ['John', 'Lydia']

In [42]: name,newlist = drawNames(newlist,"Aaron")
Drew John
New list: ['Lydia']

In [43]: name,newlist = drawNames(newlist,"Robin")
Drew Lydia
New list: []
2
qmorgan 7 grudzień 2013, 02:57

Musisz zadzwonić do rzeczywistego elementu, a nie indeks w usuwaniu. Wymień liczby z rzeczywistymi nazwami osób, które istnieją na liście, a kod powinien działać zgodnie z przeznaczeniem.

1
user6993 7 grudzień 2013, 02:24

Należy pamiętać, że istnieje potencjalna nieskończona pętla w przypadku, gdy lista Len jest liczbą nieparzystą

import random
from copy import copy
def f(name):
    x = random.choice(validNames)
    while x == name:
        x = random.choice(validNames)
    else:
        validNames.remove(x)
    return (name, x)

print map(f, copy(validNames))

>>> [('John', 'Robin'), ('Aaron', 'John'), ('Lydia', 'Aaron'), ('Robin', 'Lydia')]
0
Guy Gavriely 7 grudzień 2013, 02:41

Zdecydowanie robisz to trudny sposób.

Zamiast wielokrotnie szukają wartości listy i usuwania wartości, wystarczy przetasować listę i odczytaj pary, jak więc:

from random import shuffle

def random_pairs(lst):
    shuffle(lst)
    return zip(lst[::2], lst[1::2])

def main():
    names = 'John,Aaron,Lydia,Robin'.split(',')
    print random_pairs(names)

if __name__=="__main__":
    main()
0
Hugh Bothwell 7 grudzień 2013, 03:02
>>> from random import shuffle
>>> valid_names=["John", "Aaron", "Lydia", "Robin"]
>>> shuffle(valid_names)
>>> for pair in zip(valid_names, (valid_names*2)[1:]):
...     print(pair)
...
('Aaron', 'John')
('John', 'Lydia')
('Lydia', 'Robin')
('Robin', 'Aaron')
0
John La Rooy 7 grudzień 2013, 03:19

Najprostszym ze wszystkich jest po prostu przetasowanie nazwisk i przypisania każdej do następnego. Gwarantuje również, że dwie osoby nie będą miały żadnych nazwisk.

>>> from random import shuffle
>>> names=['John', 'Aaron', 'Lydia', 'Robin']
>>> shuffle(names)
>>> dict(zip(names, names[-1:] + names))
{'Aaron': 'Lydia', 'John': 'Robin', 'Lydia': 'John', 'Robin': 'Aaron'}
0
dansalmo 7 grudzień 2013, 03:36