কোনও তালিকা থেকে এলোমেলোভাবে কীভাবে নির্বাচন করবেন?


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পাইথন ৩.6-এ নতুন, পাইথনের পুরানো সংস্করণে আপনি random.SystemRandomক্লাসটি ব্যবহার করতে পারেন :

import random

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

3
random.choice(foo)রিটার্নের পরপর দুটি কল করা কি দুটি পৃথক ফলাফল করে?
এডুয়ার্ডো পিগনেটেলি

34
@EduardoPignatelli প্রতিটি পছন্দ, এলোমেলো হয়ে যায় তাই এটি করতে দুটি ভিন্ন ফলাফল শূণ্য কিন্তু শুরু বীজ উপর নির্ভর করে, নিশ্চিত না। আপনি নির্বাচন করতে চান, এন একটি তালিকা থেকে স্বতন্ত্র র্যান্ডম উপাদান lst , ব্যবহারrandom.sample(lst, n)
গ্রাহাম

6
সম্পর্কিত নোটে, Standard pseudo-random generators are not suitable for security/cryptographic purposes. রেফ
জিয়াও

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)

দুর্ভাগ্যক্রমে যদিও, পছন্দটি কেবল সিকোয়েন্সগুলি (যেমন তালিকা বা টিপলস) থেকে একক আউটপুট জন্য কাজ করে for যদিও 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]

সম্পাদনা: পাইথোনিক ওয়ান-লাইনার

আপনি যদি একাধিক আইটেম নির্বাচন করার জন্য আরও পাইথোনিক ওয়ান-লাইনার চান তবে আপনি আনপ্যাকিং ব্যবহার করতে পারেন।

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

1
বিটিডাব্লিউ secretsমডিউলটি পাইথন স্ট্যান্ডার্ড লাইব্রেরিতে ৩.6 পাইথন.অর্গ
দেবদেব /

160

আপনারও যদি সূচকের প্রয়োজন হয় তবে ব্যবহার করুন random.randrange

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

42

পাইথন ৩.6 হিসাবে আপনি secretsমডিউলটি ব্যবহার করতে পারেন , যা randomক্রিপ্টোগ্রাফি বা সুরক্ষা ব্যবহারের জন্য মডিউলটির চেয়ে বেশি পছন্দযোগ্য ।

একটি তালিকা থেকে একটি এলোমেলো উপাদান মুদ্রণ:

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

একটি এলোমেলো সূচক মুদ্রণ করতে:

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

বিশদগুলির জন্য, পিইপি 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.shufflelist
শ্যাডোর্যাঞ্জার

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
এছাড়াও মনে রাখবেন যে এলোমেলো.চয়েজগুলি 3.. and থেকে পাওয়া যায় এবং তারপরে, এর আগে নয়!
সিরিল এন।

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 এ নতুন New):

>>> 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')

একটি মন্তব্য:

এটি র্যান্ডম.চয়েস সত্যই এলোমেলো কিনা তা নয়। আপনি যদি বীজ স্থির করে থাকেন তবে আপনি পুনরায় উত্পাদনযোগ্য ফলাফল পাবেন - এবং এটিই বীজের জন্য ডিজাইন করা হয়েছে। আপনি 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))]
wim

2
@ উইম এটি কিছুটা হতাশাব্যঞ্জক, তবে খুব হতাশাব্যঞ্জক এটি হ'ল এর randrange()অর্থ সংজ্ঞা যেমন random.SystemRandom().randrange(3<<51)উল্লেখযোগ্য পক্ষপাতিত্ব প্রদর্শন করে। দীর্ঘশ্বাস ...
টিসি।

6
@ কেভিনস 5 শেষ পর্যন্ত এটি কারণ যে float(একটি আইইইই ডাবল) কেবল [0,1) এ সীমাবদ্ধ সংখ্যার মান নিতে পারে। Random.random()প্রচলিত উপায়ে এর আউটপুট উত্পন্ন করে: এলোমেলো পূর্ণসংখ্যা বেছে নিন [0, 2**53)এবং ভাগ করে নিন 2**53(53 একটি বিলের সংখ্যা বিট)। সুতরাং random()2 ** 53 সম্যক দ্বিগুণ প্রদান করে, এবং আপনি এটিকে N আউটপুটগুলিতে সমানভাবে ভাগ করতে পারেন কেবল যদি এন 2 এর শক্তি হয় তবে পক্ষপাত ছোট এন এর পক্ষে ছোট, তবে দেখুন collections.Counter(random.SystemRandom().randrange(3<<51)%6 for i in range(100000)).most_common()। (জাভার র্যান্ডম। এনেক্সট আইন্ট () এ জাতীয় পক্ষপাত এড়ানো হয়))
টিসি।

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))

(অজগর ২.7)


3

নিম্নলিখিত কোডগুলি আপনাকে একই আইটেমগুলি উত্পাদন করতে হবে তা প্রদর্শন করে। আপনি কতটি নমুনা বের করতে চান তাও উল্লেখ করতে পারেন। মূল জনসংখ্যা অপরিবর্তিত রেখে
এই sampleপদ্ধতিটি জনসংখ্যার উপাদানগুলি সহ একটি নতুন তালিকা প্রদান করে returns ফলাফলের তালিকাটি নির্বাচনের ক্রমে রয়েছে যাতে সমস্ত সাব-স্লাইসগুলি বৈধ এলোমেলো নমুনাও হয়ে থাকে।

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()?
অ্যালেক্সিস

"এলোমেলো.চয়েস ()" আপনাকে খালি তালিকার "সূচিপত্র: তালিকা সূচকের বাইরে" দেবে।
আব্দুল মাজিদ

6
যেমনটি হওয়া উচিত: ব্যতিক্রমগুলি এটাই। খালি তালিকা থেকে নির্বাচন করা একটি ত্রুটি। ফিরে Noneআসা কিছুটা এলোমেলো পরে বিন্দুতে লাথি মারে যেখানে অবৈধ "উপাদান" ব্যতিক্রম ঘটায়; বা আরও খারাপ, আপনি একটি ব্যতিক্রম পরিবর্তে একটি ভুল প্রোগ্রাম পান, এবং আপনি এটি জানেন না।
Alexis

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.