किसी सूची से आइटम का चयन कैसे करें?


1758

मान लें कि मेरे पास निम्नलिखित सूची है:

foo = ['a', 'b', 'c', 'd', 'e']

इस सूची से यादृच्छिक पर किसी आइटम को प्राप्त करने का सबसे सरल तरीका क्या है?

जवाबों:


2675

उपयोग random.choice()

import random

foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))

के लिए क्रिप्टोग्राफी द्वारा सुरक्षित यादृच्छिक विकल्प (उदाहरण के लिए एक wordlist से किसी पासफ़्रेज़ पैदा करने के लिए) का उपयोग करेंsecrets.choice()

import secrets

foo = ['battery', 'correct', 'horse', 'staple']
print(secrets.choice(foo))

secretsपायथन 3.6 में नया है, पायथन के पुराने संस्करणों पर आप random.SystemRandomकक्षा का उपयोग कर सकते हैं :

import random

secure_random = random.SystemRandom()
print(secure_random.choice(foo))

3
क्या random.choice(foo)रिटर्न के दो लगातार कॉल करने से दो अलग-अलग परिणाम मिलते हैं?
एडुआर्डो पिग्नाटेली

34
@EduardoPignatelli प्रत्येक विकल्प यादृच्छिक है, इसलिए यह दो अलग-अलग परिणाम लौटा सकता है , लेकिन प्रारंभ बीज के आधार पर, इसकी गारंटी नहीं है। यदि आप एक सूची lst से n अलग यादृच्छिक तत्वों का चयन करना चाहते हैं , तो उपयोग करेंrandom.sample(lst, n)
ग्राहम

6
संबंधित नोट पर, Standard pseudo-random generators are not suitable for security/cryptographic purposes. Ref
जिओ

184

यदि आप किसी सूची से किसी आइटम को रैंडमली सेलेक्ट करना चाहते हैं, या सेट से किसी आइटम का चयन करना चाहते हैं, तो मैं random.sampleइसके बजाय उपयोग करने की सलाह दूंगा।

import random
group_of_items = {1, 2, 3, 4}               # a sequence or set will work here.
num_to_select = 2                           # set the number to select here.
list_of_random_items = random.sample(group_of_items, num_to_select)
first_random_item = list_of_random_items[0]
second_random_item = list_of_random_items[1] 

यदि आप केवल एक सूची से किसी एक आइटम को खींच रहे हैं, तो पसंद कम है, क्योंकि नमूना का उपयोग random.sample(some_list, 1)[0]करने के बजाय सिंटैक्स होगा random.choice(some_list)

दुर्भाग्य से, हालांकि, विकल्प केवल अनुक्रमों से एकल आउटपुट के लिए काम करता है (जैसे सूची या ट्यूपल्स)। हालांकि random.choice(tuple(some_set))एक सेट से एक आइटम प्राप्त करने के लिए एक विकल्प हो सकता है।

संपादित करें: रहस्य का उपयोग करना

जैसा कि कई ने बताया है, यदि आपको अधिक सुरक्षित छद्म आयामी नमूनों की आवश्यकता है, तो आपको रहस्य मॉड्यूल का उपयोग करना चाहिए:

import secrets                              # imports secure module.
secure_random = secrets.SystemRandom()      # creates a secure random object.
group_of_items = {1, 2, 3, 4}               # a sequence or set will work here.
num_to_select = 2                           # set the number to select here.
list_of_random_items = secure_random.sample(group_of_items, num_to_select)
first_random_item = list_of_random_items[0]
second_random_item = list_of_random_items[1]

EDIT: पायथोनिक वन-लाइनर

यदि आप कई आइटम्स के चयन के लिए अधिक पाइथोनिक वन-लाइनर चाहते हैं, तो आप अनपैकिंग का उपयोग कर सकते हैं।

import random
first_random_item, second_random_item = random.sample(group_of_items, 2)

1
BTW secretsमॉड्यूल को संस्करण 3.6 python.org/dev/peps/pep-0506
6

160

यदि आपको भी सूचकांक की आवश्यकता है, तो उपयोग करें random.randrange

from random import randrange
random_index = randrange(len(foo))
print(foo[random_index])

42

पायथन 3.6 के रूप में आप secretsमॉड्यूल का उपयोग कर सकते हैं , जो randomक्रिप्टोग्राफी या सुरक्षा उपयोग के लिए मॉड्यूल के लिए बेहतर है ।

एक सूची से एक यादृच्छिक तत्व मुद्रित करने के लिए:

import secrets
foo = ['a', 'b', 'c', 'd', 'e']
print(secrets.choice(foo))

एक यादृच्छिक सूचकांक मुद्रित करने के लिए:

print(secrets.randbelow(len(foo)))

विवरण के लिए, PEP 506 देखें ।


33

जब तक यह खाली न हो तब तक सूची से बेतरतीब ढंग से उठाई गई वस्तुओं को हटाने के लिए मैं एक स्क्रिप्ट प्रस्तावित करता हूं:

एक बनाए रखने के लिए setऔर बेतरतीब ढंग से उठाया तत्व (साथ हटाने choice) जब तक सूची खाली है।

s=set(range(1,6))
import random

while len(s)>0:
  s.remove(random.choice(list(s)))
  print(s)

तीन रन तीन अलग-अलग जवाब देते हैं:

>>> 
set([1, 3, 4, 5])
set([3, 4, 5])
set([3, 4])
set([4])
set([])
>>> 
set([1, 2, 3, 5])
set([2, 3, 5])
set([2, 3])
set([2])
set([])

>>> 
set([1, 2, 3, 5])
set([1, 2, 3])
set([1, 2])
set([1])
set([])

20
या आप केवल random.shuffleएक listबार कर सकते हैं और या तो इसे पुनरावृत्त कर सकते हैं या परिणाम उत्पन्न करने के लिए इसे पॉप कर सकते हैं। या तो एक पूरी तरह से पर्याप्त "कोई पुनरावृत्ति के साथ यादृच्छिक रूप से चयन करें" स्ट्रीम में परिणाम होगा, यह सिर्फ यह है कि यादृच्छिकता शुरुआत में पेश की जाएगी।
शैडो रेंजर

2
सैद्धांतिक रूप से आप एक सेट से एक मनमाना तत्व को हटाने और उसे वापस करने के लिए एक सेट के पॉप () विधि का उपयोग कर सकते हैं , लेकिन यह संभवतः पर्याप्त यादृच्छिक नहीं है।
जौबर्क

14
foo = ['a', 'b', 'c', 'd', 'e']
number_of_samples = 1

अजगर 2 में:

random_items = random.sample(population=foo, k=number_of_samples)

अजगर 3 में:

random_items = random.choices(population=foo, k=number_of_samples)

6
ध्यान दें कि random.choicesप्रतिस्थापन के साथ है जबकि random.sampleप्रतिस्थापन के बिना है।
सेंटुआ

1
यह भी ध्यान दें कि random.choices 3.6 और बाद में उपलब्ध है, पहले नहीं!
सिरिल एन।

11

numpy समाधान: numpy.random.choice

इस प्रश्न के लिए, यह स्वीकृत उत्तर ( import random; random.choice()) के समान ही काम करता है , लेकिन मैंने इसे इसलिए जोड़ा क्योंकि प्रोग्रामर ने numpyपहले से ही आयात किया होगा (मेरी तरह) और साथ ही दो तरीकों के बीच कुछ अंतर हैं जो आपके वास्तविक उपयोग के मामले को चिंतित कर सकते हैं।

import numpy as np    
np.random.choice(foo) # randomly selects a single item

प्रजनन के लिए, आप कर सकते हैं:

np.random.seed(123)
np.random.choice(foo) # first call will always return 'c'

एक या एक से अधिक वस्तुओं के नमूनों के लिए , एक के रूप में लौटा array, sizeतर्क पास करें :

np.random.choice(foo, 5)          # sample with replacement (default)
np.random.choice(foo, 5, False)   # sample without replacement

9

किसी सूची से आइटम का चयन कैसे करें?

मान लें कि मेरे पास निम्नलिखित सूची है:

foo = ['a', 'b', 'c', 'd', 'e']  

इस सूची से यादृच्छिक पर किसी आइटम को प्राप्त करने का सबसे सरल तरीका क्या है?

यदि आप वास्तव में यादृच्छिक के करीब चाहते हैं , तो मैं secrets.choiceमानक पुस्तकालय से सुझाव देता हूं (पायथन 3.6 में नया।)।

>>> from secrets import choice         # Python 3 only
>>> choice(list('abcde'))
'c'

उपरोक्त मेरी पूर्व सिफारिश के बराबर है, विधि के साथ मॉड्यूल SystemRandomसे एक वस्तु का उपयोग करके - पहले पायथन 2 में उपलब्ध है:randomchoice

>>> import random                      # Python 2 compatible
>>> sr = random.SystemRandom()
>>> foo = list('abcde')
>>> foo
['a', 'b', 'c', 'd', 'e']

और अब:

>>> sr.choice(foo)
'd'
>>> sr.choice(foo)
'e'
>>> sr.choice(foo)
'a'
>>> sr.choice(foo)
'b'
>>> sr.choice(foo)
'a'
>>> sr.choice(foo)
'c'
>>> sr.choice(foo)
'c'

यदि आप एक नियतात्मक छद्म आयामी चयन चाहते हैं, तो choiceफ़ंक्शन का उपयोग करें (जो वास्तव में एक Randomवस्तु पर एक बाध्य विधि है ):

>>> random.choice
<bound method Random.choice of <random.Random object at 0x800c1034>>

यह यादृच्छिक लगता है, लेकिन यह वास्तव में नहीं है, जिसे हम देख सकते हैं कि क्या हम इसे बार-बार बदलते हैं:

>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')

एक टिप्पणी:

यह इस बारे में नहीं है कि random.choice वास्तव में यादृच्छिक है या नहीं। यदि आप बीज को ठीक करते हैं, तो आपको प्रजनन योग्य परिणाम प्राप्त होंगे - और यही बीज के लिए डिज़ाइन किया गया है। आप एक बीज को SystemRandom भी पास कर सकते हैं।sr = random.SystemRandom(42)

ठीक है, हाँ आप इसे एक "बीज" तर्क पास कर सकते हैं, लेकिन आप देखेंगे कि SystemRandomवस्तु इसे अनदेखा करती है :

def seed(self, *args, **kwds):
    "Stub method.  Not used for a system random number generator."
    return None

8

यदि आपको सूचकांक का उपयोग करने की आवश्यकता है:

import random
foo = ['a', 'b', 'c', 'd', 'e']
print int(random.random() * len(foo))
print foo[int(random.random() * len(foo))]

random.choice वही करता है :)


2
@tc। दरअसल, यह अनिवार्य रूप से एक ही करता है। का कार्यान्वयन random.choice(self, seq)है return seq[int(self.random() * len(seq))]
विम

2
@ यह थोड़ा निराशाजनक है, लेकिन बहुत निराशाजनक बात यह है कि इसकी परिभाषा भी है, randrange()जिसका मतलब है कि random.SystemRandom().randrange(3<<51)महत्वपूर्ण पूर्वाग्रह प्रदर्शित करता है। आह ...
टीसी।

6
@ kevinsa5 अंततः यह इसलिए है क्योंकि float(एक IEEE डबल) केवल [0,1) में मानों की एक सीमित संख्या ले सकता है। Random.random()अपने आउटपुट को पारंपरिक तरीके से उत्पन्न करता है: एक यादृच्छिक पूर्णांक चुनें [0, 2**53)और विभाजित करें 2**53(53 एक डबल में बिट्स की संख्या है)। तो random()2 ** 53 से लैस होने वाले युगल लौटाता है, और आप इसे एन आउटपुट में समान रूप से विभाजित कर सकते हैं, यदि एन 2 की शक्ति है। पूर्वाग्रह छोटे एन के लिए छोटा है, लेकिन देखें collections.Counter(random.SystemRandom().randrange(3<<51)%6 for i in range(100000)).most_common()। (जावा के random.nextInt () इस तरह के पूर्वाग्रह से बचा जाता है।)
टीसी।

1
@tc। मुझे लगता है कि कुछ भी कम नहीं है 2**40, (जो 1099511627776 है), पूर्वाग्रह के लिए काफी छोटा होगा जो व्यवहार में मायने नहीं रखता है? यह वास्तव में प्रलेखन में इंगित किया जाना चाहिए, क्योंकि यदि कोई व्यक्ति सावधानीपूर्वक नहीं है, तो वे अपने कोड के इस हिस्से से आने की समस्याओं की उम्मीद नहीं कर सकते हैं।
एवगेनी सर्गेव

@tc .: वास्तव में, बड़ी संख्या के लिए परिणाम उत्पन्न करने के लिए पर्याप्त संख्या में बिट्स प्राप्त करने के लिए randomउपयोग करता getrandbitsहै randrange( random.choiceवह भी उपयोग कर रहा है)। यह 2.7 और 3.5 दोनों पर सच है। यह केवल self.random() * len(seq)तब उपयोग करता है जब getrandbitsउपलब्ध नहीं होता है। यह बेवकूफी की बात नहीं है जो आपको लगता है कि यह है।
शैडो रेंजर

7

यह एक चर वाला कोड है जो यादृच्छिक सूचकांक को परिभाषित करता है:

import random

foo = ['a', 'b', 'c', 'd', 'e']
randomindex = random.randint(0,len(foo)-1) 
print (foo[randomindex])
## print (randomindex)

यह चर के बिना कोड है:

import random

foo = ['a', 'b', 'c', 'd', 'e']
print (foo[random.randint(0,len(foo)-1)])

और यह इसे करने के लिए सबसे छोटा और सबसे चतुर तरीका है।

import random

foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))

(अजगर २. p)


3

निम्न कोड प्रदर्शित करता है कि क्या आपको समान वस्तुओं का उत्पादन करने की आवश्यकता है। आप यह भी निर्दिष्ट कर सकते हैं कि आप कितने नमूने निकालना चाहते हैं। विधि आबादी से तत्वों से युक्त जबकि मूल आबादी अपरिवर्तित छोड़ एक नई सूची देता है। परिणामी सूची चयन क्रम में है ताकि सभी उप-स्लाइस भी वैध यादृच्छिक नमूने होंगे।
sample

import random as random
random.seed(0)  # don't use seed function, if you want different results in each run
print(random.sample(foo,3))  # 3 is the number of sample you want to retrieve

Output:['d', 'e', 'a']

1

रैंडम आइटम चयन:

import random

my_list = [1, 2, 3, 4, 5]
num_selections = 2

new_list = random.sample(my_list, num_selections)

सूची के क्रम को बनाए रखने के लिए, आप यह कर सकते हैं:

randIndex = random.sample(range(len(my_list)), n_selections)
randIndex.sort()
new_list = [my_list[i] for i in randIndex]

Https://stackoverflow.com/a/49682832/4383027 का डुप्लीकेट


0

हम रैंडिंट का उपयोग करके भी ऐसा कर सकते हैं।

from random import randint
l= ['a','b','c']

def get_rand_element(l):
    if l:
        return l[randint(0,len(l)-1)]
    else:
        return None

get_rand_element(l)

19
पृथ्वी पर आप इसे इस तरह से क्यों करेंगे, जब वहाँ random.choice()और random.randrange()?
एलेक्सिस

"random.choice ()" आपको खाली सूची पर "IndexError: list index out of range" देगा।
अब्दुल मजीद

6
जैसा कि यह होना चाहिए: कि अपवाद क्या हैं। खाली सूची से चयन करना एक त्रुटि है। रिटर्निंग Noneबस कैन को कुछ यादृच्छिक बाद में इंगित करता है जहां अमान्य "तत्व" एक अपवाद को ट्रिगर करता है; या इससे भी बदतर, आपको एक अपवाद के बजाय एक गलत कार्यक्रम मिलता है, और आपको यह भी पता नहीं है।
एलेक्सिस

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.