2014-01-18 29 views
-4

我必須使用random.randint從python 中的列表中隨機選擇名稱。如何從列表中選擇隨機名而無需在python中重複使用

到目前爲止我已經完成了。但我無法弄清楚如何不重複地打印它們。 某些名字在10到15個名字後重復。

請幫我一把。 我不允許使用任何高級功能。我應該用簡單的功能來做。這是我的程序。

import random 
names = [about 150 names] 
print([names[random.randint(0, len(names)-1)] for i in range(user_input)]) 
+0

你被允許使用「隨機」庫,所以我假設你被允許使用HTTP洗牌:/ /stackoverflow.com/questions/976882/shuffling-a-list-of-objects-in-python – sashkello

+1

作爲一個附註,從來沒有一個很好的理由使用'foo [randint(0,len(foo)-1) ]'。首先,這只是一個更復雜(更容易出錯)的方式來編寫'foo [randrange(len(foo))]''。更重要的是,即使這只是一個更復雜(更容易出錯)的方式來編寫'choice(foo)'。 – abarnert

回答

2

如果你能破壞性修改names,只是pop值而不是複製它們。然後他們不在了,所以你將無法重複。

如果你不能破壞性修改names,只是做同樣的副本:

tmp = names[:] 
result = [tmp.pop(random.randrange(len(tmp))) for _ in range(user_input)] 

這確實有二次性能,因爲每個pop從列表中的中間有轉移一半列表向上一個缺口。但對於150個名字,這不太可能是一個問題。例如,在我的筆記本電腦上,從150個名稱中挑選100個值需要83微秒。

如果你真的是不允許使用,甚至randrange,你可以把它寫自己:

def randrange(x): return randint(0, x-1) 
+1

'copy'是標準模塊的名稱之一。 – thefourtheye

+0

+1,但OP只想使用'randint'。 – thefourtheye

+0

@thefourtheye:根據其他人(尤其是如果你甚至撇過文檔)寫'randrange'或'randint',這是很微不足道的,我認爲它甚至不需要解釋。但我已經將它添加到答案以防萬一。你對使用'copy'的想法是正確的,而且它也使我的代碼太接近80列。固定。 – abarnert

0

假設,你只能使用randint和基本操作(循環,分配和sublistings) - 你可以做「到位洗牌技巧」(費舍爾耶茨的現代版本)來實現這樣的結果

copy = names[:]  
for i in xrange(user_input-1, 1, -1): 
    swap = random.randint(0, i) 
    copy[i],copy[swap] = copy[swap],copy[i] 

print copy[ :user_input ] 
+1

您不需要3行代碼或臨時變量來交換Python中的兩個值,只需'copy [i],copy [swap] = copy [swap],copy [i]'。 – abarnert

+2

這是一個非統一的洗牌。改爲使用Fisher Yates。 –

+0

大衛 - 謝謝你指出我錯過了範圍,現在它是一個正確的風險 – lejlot

-1

生成相同的長度的隨機數的數組作爲names

sortarr = [random.randint(0, 10*len(names)) for i in range(len(names))] 

和排序您names基於陣列的新陣列

names = [name for sa, name in sorted(zip(sortarr, names))] 

上它所做的是一些隨機數到names分配。它們可以重複,但不會重複名稱,因爲如果兩個數字相同,它們將被分配一些任意名稱。

+0

我不明白你的觀點。可能是因爲我是新程序員。 如果你能向我解釋你的觀點,我將非常感謝你的努力。 – user3209210

+0

這不會做任何事情來避免重複。乘以10使他們有點不太可能,但它實際上並沒有解決問題。 – abarnert

+0

對於證據,試試這個:'範圍(len(name))})的範圍(1000))/ 1000.0'的sum(len({randint(10 * len(names))。它將在142.8左右,這意味着平均來說,選擇150個值會爲您提供142.8個獨特值和7.2個重複。 (或者你可以運行你的代碼一次,看看結果;沒有重複的機率很渺茫。) – abarnert

1

這些限制非常愚蠢。我不確定什麼是「高級功能」,但是在我提供the function in your last question之後仍然需要幫助,因此可能函數聲明是不允許的?

不過,您可以在沒有功能的情況下做同樣的事情。你只需要跟蹤你已經使用過的指標。這裏的另一個走:

indices = [] 
for x in range(5): 
    index = random.randint(0, len(population)-1) 
    while index in indices: 
     index = random.randint(0, len(population)-1) 
    indices.append(index) 
names = [population[i] for i in indices] 
+0

OP,我真的會推薦@ abarnert的答案。 – jayelm

相關問題