मैं डुप्लिकेट के बिना यादृच्छिक संख्याओं की सूची कैसे बनाऊं?


110

मैंने उपयोग करने की कोशिश की random.randint(0, 100), लेकिन कुछ संख्याएं समान थीं। क्या कोई सूची / यादृच्छिक यादृच्छिक संख्या बनाने के लिए कोई विधि / मॉड्यूल है?

नोट: निम्नलिखित कोड एक उत्तर पर आधारित है और उत्तर पोस्ट किए जाने के बाद जोड़ा गया है। यह सवाल का हिस्सा नहीं है; इसका हल है।

def getScores():
    # open files to read and write
    f1 = open("page.txt", "r");
    p1 = open("pgRes.txt", "a");

    gScores = [];
    bScores = [];
    yScores = [];

    # run 50 tests of 40 random queries to implement "bootstrapping" method 
    for i in range(50):
        # get 40 random queries from the 50
        lines = random.sample(f1.readlines(), 40);

1
यदि वे अद्वितीय हैं तो वे सही संदर्भ में सही मायने में यादृच्छिक हो सकते हैं। प्रतिस्थापन के बिना अनुक्रमित के एक यादृच्छिक नमूने की तरह अभी भी पूरी तरह से यादृच्छिक हो सकता है।
gbtimmon

जवाबों:


180

यह डुप्लिकेट के बिना, 0 से 99 तक की सीमा से चुने गए 10 नंबरों की सूची लौटाएगा।

import random
random.sample(range(100), 10)

अपने विशिष्ट कोड उदाहरण के संदर्भ में, आप संभवतः फ़ाइल से सभी लाइनों को एक बार पढ़ना चाहते हैं और फिर मेमोरी में सहेजी गई सूची से यादृच्छिक लाइनों का चयन करें। उदाहरण के लिए:

all_lines = f1.readlines()
for i in range(50):
    lines = random.sample(all_lines, 40)

इस तरह, आपको केवल अपने लूप से पहले फ़ाइल से एक बार वास्तव में पढ़ना होगा। ऐसा करने के लिए फ़ाइल की शुरुआत में वापस लेने और f1.readlines()प्रत्येक लूप पुनरावृत्ति के लिए फिर से कॉल करने की तुलना में यह अधिक कुशल है ।


2
यह तकनीक स्मृति को बर्बाद करती है, विशेष रूप से बड़े नमूनों के लिए। मैंने एक बहुत अधिक मेमोरी के लिए कोड पोस्ट किया है और नीचे दिए गए कुशल समाधान की गणना करता है जो एक रैखिक बधाई जेनरेटर का उपयोग करता है।
थॉमस लक्स

यह मेरे लिए इंगित किया गया था कि एलसीजी विधि कम "यादृच्छिक" है, लेकिन यदि आप कई अद्वितीय यादृच्छिक अनुक्रम उत्पन्न करना चाहते हैं, तो विविधता इस समाधान से कम होगी। यदि आपको केवल कुछ क्रमबद्ध यादृच्छिक दृश्यों की आवश्यकता है, तो LCG जाने का रास्ता है!
थॉमस लक्स

धन्यवाद ग्रेग, यह उपयोगी था
एन शिवराम

15

आप इस तरह यादृच्छिक मॉड्यूल से फेरबदल समारोह का उपयोग कर सकते हैं :

import random

my_list = list(xrange(1,100)) # list of integers from 1 to 99
                              # adjust this boundaries to fit your needs
random.shuffle(my_list)
print my_list # <- List of unique random numbers

यहां ध्यान दें कि फेरबदल विधि किसी भी सूची को वापस नहीं करती है क्योंकि कोई भी उम्मीद कर सकता है, यह केवल संदर्भ द्वारा पारित सूची को फेरबदल करता है।


यहाँ यह उल्लेख करना अच्छा है कि xrange केवल पायथन 2 में काम करता है न कि पायथन 3 में
शायन शफीक

10

आप पहले से नंबरों की सूची बना सकते हैं aकरने के लिए bहै, जहां aऔर bक्रमश: अपनी सूची में सबसे छोटी और सबसे बड़ी संख्या है, तो इसके साथ शफ़ल फिशर-येट्स एल्गोरिथ्म या अजगर का उपयोग random.shuffleविधि।


1
सूचकांकों की पूरी सूची बनाना स्मृति की बर्बादी है, खासकर बड़े नमूनों के लिए। मैंने एक बहुत अधिक मेमोरी के लिए कोड पोस्ट किया है और नीचे दिए गए कुशल समाधान की गणना करता है जो एक रैखिक बधाई जेनरेटर का उपयोग करता है।
थॉमस लक्स

8

इस उत्तर में प्रस्तुत समाधान काम करता है, लेकिन नमूना आकार छोटा होने पर यह स्मृति के साथ समस्याग्रस्त हो सकता है, लेकिन जनसंख्या बहुत बड़ी है (उदाहरण के लिए random.sample(insanelyLargeNumber, 10))।

इसे ठीक करने के लिए, मैं इसके साथ जाऊंगा:

answer = set()
sampleSize = 10
answerSize = 0

while answerSize < sampleSize:
    r = random.randint(0,100)
    if r not in answer:
        answerSize += 1
        answer.add(r)

# answer now contains 10 unique, random integers from 0.. 100

अब random.sampleबड़ी आबादी से छोटी संख्या में नमूनों के लिए इस दृष्टिकोण का उपयोग करता है, इसलिए स्मृति के साथ यह समस्या वास्तव में अब मौजूद नहीं है। हालाँकि, जिस समय यह उत्तर लिखा गया था, उस समय का कार्यान्वयन random.shuffleभिन्न हो सकता है।
कीरिल

5

रैखिक बधाई छद्म यादृच्छिक संख्या जनरेटर

ओ (१) स्मृति

ओ (के) संचालन

इस समस्या को एक सरल रैखिक संघटक जनरेटर के साथ हल किया जा सकता है । इसके लिए निरंतर मेमोरी ओवरहेड (8 पूर्णांक) और अधिकतम 2 * (अनुक्रम लंबाई) कंप्यूटेशन की आवश्यकता होती है।

अन्य सभी समाधान अधिक मेमोरी और अधिक गणना का उपयोग करते हैं! यदि आपको केवल कुछ यादृच्छिक अनुक्रमों की आवश्यकता है, तो यह विधि काफी सस्ती होगी। आकार की श्रेणियों के लिए N, यदि आप Nअनूठे- kपरिणाम या अधिक के आदेश पर उत्पन्न करना चाहते हैं, तो मैं बिलिन विधियों का उपयोग करके स्वीकृत समाधान की सिफारिश करता हूं random.sample(range(N),k)क्योंकि यह गति के लिए अजगर में अनुकूलित किया गया है

कोड

# Return a randomized "range" using a Linear Congruential Generator
# to produce the number sequence. Parameters are the same as for 
# python builtin "range".
#   Memory  -- storage for 8 integers, regardless of parameters.
#   Compute -- at most 2*"maximum" steps required to generate sequence.
#
def random_range(start, stop=None, step=None):
    import random, math
    # Set a default values the same way "range" does.
    if (stop == None): start, stop = 0, start
    if (step == None): step = 1
    # Use a mapping to convert a standard range into the desired range.
    mapping = lambda i: (i*step) + start
    # Compute the number of numbers in this range.
    maximum = (stop - start) // step
    # Seed range with a random integer.
    value = random.randint(0,maximum)
    # 
    # Construct an offset, multiplier, and modulus for a linear
    # congruential generator. These generators are cyclic and
    # non-repeating when they maintain the properties:
    # 
    #   1) "modulus" and "offset" are relatively prime.
    #   2) ["multiplier" - 1] is divisible by all prime factors of "modulus".
    #   3) ["multiplier" - 1] is divisible by 4 if "modulus" is divisible by 4.
    # 
    offset = random.randint(0,maximum) * 2 + 1      # Pick a random odd-valued offset.
    multiplier = 4*(maximum//4) + 1                 # Pick a multiplier 1 greater than a multiple of 4.
    modulus = int(2**math.ceil(math.log2(maximum))) # Pick a modulus just big enough to generate all numbers (power of 2).
    # Track how many random numbers have been returned.
    found = 0
    while found < maximum:
        # If this is a valid value, yield it in generator fashion.
        if value < maximum:
            found += 1
            yield mapping(value)
        # Calculate the next value in the sequence.
        value = (value*multiplier + offset) % modulus

प्रयोग

इस फ़ंक्शन "random_range" का उपयोग किसी भी जनरेटर (जैसे "रेंज") के लिए समान है। एक उदाहरण:

# Show off random range.
print()
for v in range(3,6):
    v = 2**v
    l = list(random_range(v))
    print("Need",v,"found",len(set(l)),"(min,max)",(min(l),max(l)))
    print("",l)
    print()

नमूना परिणाम

Required 8 cycles to generate a sequence of 8 values.
Need 8 found 8 (min,max) (0, 7)
 [1, 0, 7, 6, 5, 4, 3, 2]

Required 16 cycles to generate a sequence of 9 values.
Need 9 found 9 (min,max) (0, 8)
 [3, 5, 8, 7, 2, 6, 0, 1, 4]

Required 16 cycles to generate a sequence of 16 values.
Need 16 found 16 (min,max) (0, 15)
 [5, 14, 11, 8, 3, 2, 13, 1, 0, 6, 9, 4, 7, 12, 10, 15]

Required 32 cycles to generate a sequence of 17 values.
Need 17 found 17 (min,max) (0, 16)
 [12, 6, 16, 15, 10, 3, 14, 5, 11, 13, 0, 1, 4, 8, 7, 2, ...]

Required 32 cycles to generate a sequence of 32 values.
Need 32 found 32 (min,max) (0, 31)
 [19, 15, 1, 6, 10, 7, 0, 28, 23, 24, 31, 17, 22, 20, 9, ...]

Required 64 cycles to generate a sequence of 33 values.
Need 33 found 33 (min,max) (0, 32)
 [11, 13, 0, 8, 2, 9, 27, 6, 29, 16, 15, 10, 3, 14, 5, 24, ...]

1
यह बहुत अच्छा है! लेकिन मुझे यकीन है कि यह वास्तव में सवाल का जवाब देता है; मैं 0 से 4 तक 2 मानों का नमूना लेना चाहता हूं। अपने स्वयं के उत्पादन के बिना prime, फ़ंक्शन केवल मुझे 4 संभावित उत्तर लौटाएगा, क्योंकि value4 संभावित मूल्यों के साथ एकमात्र यादृच्छिक रूप से चुनी गई चीज है, जब हमें कम से कम (4 चुनने 2) = की आवश्यकता होती है 6, (गैर-यादृच्छिक आदेश के लिए अनुमति)। random_range(2,4)मान {(1, 0), (3, 2), (2, 1), (0, 3)} पर लौटाएंगे, लेकिन कभी भी जोड़ी (3,1) (या (1,3)) नहीं होगी। क्या आप नए बेतरतीब ढंग से उत्पन्न बड़े primes प्रत्येक फ़ंक्शन कॉल की उम्मीद कर रहे हैं?
wowserx

1
(इसके अलावा, यह मानते हुए कि आप उम्मीद करते हैं कि लोग आपके फ़ंक्शन को इसे वापस करने के बाद अनुक्रम में फेरबदल करेंगे यदि वे यादृच्छिक क्रम चाहते हैं, तो इसके बजाय अनूठे दृश्यों के random_range(v)लिए रिटर्न vकरते हैं v!)
wowserx

पूर्णतया सत्य! पूर्णांक ओवरफ़्लो से बचने और पर्याप्त यादृच्छिक क्रम उत्पन्न करने के बीच संतुलन बनाना कठिन है। मैंने फ़ंक्शन को थोड़ा और यादृच्छिकता शामिल करने के लिए अपडेट किया, लेकिन यह अभी भी v जितना यादृच्छिक नहीं है! यह इस बात पर निर्भर करता है कि आप फ़ंक्शन को कई बार उपयोग करना चाहते हैं या नहीं। इस समाधान का सबसे अच्छा उपयोग किया जाता है जब आप बड़ी मात्रा में मूल्यों से उत्पन्न हो रहे हैं (जब दूसरों की मेमोरी खपत बहुत अधिक होगी)। मैं इसे और अधिक सोचूंगा, धन्यवाद!
थॉमस लक्स

4

यदि 1 से एन तक एन संख्याओं की सूची यादृच्छिक रूप से उत्पन्न होती है, तो हां, एक संभावना है कि कुछ संख्याओं को दोहराया जा सकता है।

यदि आप यादृच्छिक क्रम में 1 से एन की संख्या की सूची चाहते हैं, तो 1 से एन तक पूर्णांक के साथ एक सरणी भरें, और फिर फिशर-येट्स फेरबदल या पायथन का उपयोग करें random.shuffle()


3

यदि आपको बहुत बड़ी संख्या में नमूना लेने की आवश्यकता है, तो आप उपयोग नहीं कर सकते range

random.sample(range(10000000000000000000000000000000), 10)

क्योंकि यह फेंकता है:

OverflowError: Python int too large to convert to C ssize_t

साथ ही, यदि random.sampleरेंज बहुत छोटी होने के कारण आपको इच्छित आइटमों की संख्या उत्पन्न नहीं हो सकती है

 random.sample(range(2), 1000)

यह फेंकता है:

 ValueError: Sample larger than population

यह फ़ंक्शन दोनों समस्याओं का समाधान करता है:

import random

def random_sample(count, start, stop, step=1):
    def gen_random():
        while True:
            yield random.randrange(start, stop, step)

    def gen_n_unique(source, n):
        seen = set()
        seenadd = seen.add
        for i in (i for i in source() if i not in seen and not seenadd(i)):
            yield i
            if len(seen) == n:
                break

    return [i for i in gen_n_unique(gen_random,
                                    min(count, int(abs(stop - start) / abs(step))))]

अत्यंत बड़ी संख्या के साथ उपयोग:

print('\n'.join(map(str, random_sample(10, 2, 10000000000000000000000000000000))))

नमूना परिणाम:

7822019936001013053229712669368
6289033704329783896566642145909
2473484300603494430244265004275
5842266362922067540967510912174
6775107889200427514968714189847
9674137095837778645652621150351
9969632214348349234653730196586
1397846105816635294077965449171
3911263633583030536971422042360
9864578596169364050929858013943

उपयोग जहां सीमा अनुरोधित वस्तुओं की संख्या से छोटी है:

print(', '.join(map(str, random_sample(100000, 0, 3))))

नमूना परिणाम:

2, 0, 1

यह नकारात्मक सीमाओं और चरणों के साथ भी काम करता है:

print(', '.join(map(str, random_sample(10, 10, -10, -2))))
print(', '.join(map(str, random_sample(10, 5, -5, -2))))

नमूना परिणाम:

2, -8, 6, -2, -4, 0, 4, 10, -6, 8
-3, 1, 5, -1, 3

क्या होगा यदि आप 8 बिलियन से अधिक संख्याएँ उत्पन्न करते हैं, तो जल्द ही या बाद में देखा जाने वाला बहुत बड़ा हो जाएगा
david_adler

इस जवाब में बड़े नमूनों के लिए एक गंभीर दोष है। टक्कर की संभावना प्रत्येक चरण के साथ रैखिक रूप से बढ़ती है। मैंने एक लाइनियर कॉनग्रेशनल जेनरेटर का उपयोग करके एक समाधान पोस्ट किया है जिसमें ओ (1) मेमोरी ओवरहेड और के (जे) के के नम्बर उत्पन्न करने के लिए आवश्यक कदम हैं। यह बहुत अधिक कुशलता से हल किया जा सकता है!
थॉमस लक्स

यह उत्तर निश्चित रूप से बेहतर है यदि आप अनुक्रम की लंबाई के क्रम पर कई यादृच्छिक अनुक्रम उत्पन्न करना चाहते हैं! एलसीजी विधि कम "यादृच्छिक" है जब यह कई अद्वितीय अनुक्रम उत्पन्न करने की बात आती है।
थॉमस लक्स

"यह फ़ंक्शन दोनों समस्याओं को हल करता है" यह दूसरी समस्या को कैसे हल करता है? आप अभी भी 2 की आबादी से 1000 नमूने नहीं ले सकते हैं। एक अपवाद को फेंकने के बजाय आप एक गलत परिणाम उत्पन्न करते हैं; कि शायद ही "समस्या" के एक संकल्प है (जो वास्तव में एक समस्या यह अनुरोध के लिए सभी उचित नहीं है, क्योंकि के साथ शुरू करने के लिए नहीं है कश्मीर अद्वितीय नमूने की आबादी से n <कश्मीर )।
14

1

आप Numpy का उपयोग कर सकते हैंनीचे दिए गए त्वरित उत्तर के लिए लाइब्रेरी का -

दिए गए कोड स्निपेट 0 से 5. की सीमा के बीच 6 अद्वितीय नंबरों को सूचीबद्ध करता है। आप अपने आराम के लिए मापदंडों को समायोजित कर सकते हैं।

import numpy as np
import random
a = np.linspace( 0, 5, 6 )
random.shuffle(a)
print(a)

उत्पादन

[ 2.  1.  5.  3.  4.  0.]

जैसा कि हमने यहां बताया है यह किसी भी तरह की अड़चन नहीं डालता है जैसा कि हम random.sample में देखते हैं

उम्मीद है इससे कुछ मदद मिली होगी।


1

यहाँ प्रदान किया गया उत्तर समय के साथ-साथ स्मृति के साथ बहुत अच्छा काम करता है लेकिन थोड़ा और अधिक जटिल है क्योंकि यह उपज जैसे उन्नत अजगर निर्माण का उपयोग करता है। सरल जवाब व्यवहार में अच्छी तरह से काम करता है लेकिन, कि जवाब के साथ मुद्दा यह है कि यह वास्तव में आवश्यक सेट निर्माण करने से पहले कई नकली पूर्णांकों उत्पन्न हो सकता है है। जनसंख्या के साथ इसे आज़माएं = 1000, नमूना करें = 999। सिद्धांत में, एक मौका है कि यह समाप्त नहीं होता है।

नीचे दिए गए जवाब दोनों मुद्दों को संबोधित करते हैं, क्योंकि यह नियतात्मक और कुछ हद तक कुशल है, हालांकि वर्तमान में अन्य दो की तरह कुशल नहीं है।

def randomSample(populationSize, sampleSize):
  populationStr = str(populationSize)
  dTree, samples = {}, []
  for i in range(sampleSize):
    val, dTree = getElem(populationStr, dTree, '')
    samples.append(int(val))
  return samples, dTree

जहां कार्य मिलते हैं, नीचे दिए गए अनुसार percolateUp को परिभाषित किया गया है

import random

def getElem(populationStr, dTree, key):
  msd  = int(populationStr[0])
  if not key in dTree.keys():
    dTree[key] = range(msd + 1)
  idx = random.randint(0, len(dTree[key]) - 1)
  key = key +  str(dTree[key][idx])
  if len(populationStr) == 1:
    dTree[key[:-1]].pop(idx)
    return key, (percolateUp(dTree, key[:-1]))
  newPopulation = populationStr[1:]
  if int(key[-1]) != msd:
    newPopulation = str(10**(len(newPopulation)) - 1)
  return getElem(newPopulation, dTree, key)

def percolateUp(dTree, key):
  while (dTree[key] == []):
    dTree[key[:-1]].remove( int(key[-1]) )
    key = key[:-1]
  return dTree

अंत में, समय का औसत बड़े मूल्य के लिए लगभग 15ms था, जैसा कि नीचे दिखाया गया है,

In [3]: n = 10000000000000000000000000000000

In [4]: %time l,t = randomSample(n, 5)
Wall time: 15 ms

In [5]: l
Out[5]:
[10000000000000000000000000000000L,
 5731058186417515132221063394952L,
 85813091721736310254927217189L,
 6349042316505875821781301073204L,
 2356846126709988590164624736328L]

आपको लगता है कि जवाब जटिल है? यह क्या है ?! और फिर एक और उत्तर है , जो कई "स्प्रिचुअल पूर्णांक" उत्पन्न करता है। मैंने आपके कार्यान्वयन को आपके द्वारा दिए गए उदाहरण इनपुट के साथ चलाया (जनसंख्या = 1000, नमूना आकार = 999)। आपका संस्करण random.randintफ़ंक्शन को 3996 बार कॉल करता है , जबकि अन्य एक cca। 6000 गुना। नहीं एक बड़ा सुधार हुह?
कीरिल

@ सिरिल, आपका उत्तर इस
aak318

1

एक प्रोग्राम प्राप्त करने के लिए जो डुप्लिकेट के बिना यादृच्छिक मूल्यों की एक सूची बनाता है जो कि नियतात्मक, कुशल है और बुनियादी प्रोग्रामिंग निर्माणों के साथ बनाया extractSamplesगया है, नीचे दिए गए फ़ंक्शन पर विचार करें।

def extractSamples(populationSize, sampleSize, intervalLst) :
    import random
    if (sampleSize > populationSize) :
        raise ValueError("sampleSize = "+str(sampleSize) +" > populationSize (= " + str(populationSize) + ")")
    samples = []
    while (len(samples) < sampleSize) :
        i = random.randint(0, (len(intervalLst)-1))
        (a,b) = intervalLst[i]
        sample = random.randint(a,b)
        if (a==b) :
            intervalLst.pop(i)
        elif (a == sample) : # shorten beginning of interval                                                                                                                                           
            intervalLst[i] = (sample+1, b)
        elif ( sample == b) : # shorten interval end                                                                                                                                                   
            intervalLst[i] = (a, sample - 1)
        else :
            intervalLst[i] = (a, sample - 1)
            intervalLst.append((sample+1, b))
        samples.append(sample)
    return samples

मूल विचार intervalLstसंभव मूल्यों के लिए अंतराल का ट्रैक रखना है जिसमें से हमारे आवश्यक तत्वों का चयन करना है। यह इस अर्थ में नियतात्मक है कि हम निश्चित संख्या में चरणों के भीतर एक नमूना उत्पन्न करने की गारंटी देते हैं (पूरी तरह से निर्भर populationSizeऔरsampleSize )।

हमारी आवश्यक सूची बनाने के लिए उपरोक्त फ़ंक्शन का उपयोग करने के लिए,

In [3]: populationSize, sampleSize = 10**17, 10**5

In [4]: %time lst1 = extractSamples(populationSize, sampleSize, [(0, populationSize-1)])
CPU times: user 289 ms, sys: 9.96 ms, total: 299 ms
Wall time: 293 ms

हम पहले के समाधान के साथ तुलना भी कर सकते हैं (जनसंख्या के कम मूल्य के लिए)

In [5]: populationSize, sampleSize = 10**8, 10**5

In [6]: %time lst = random.sample(range(populationSize), sampleSize)
CPU times: user 1.89 s, sys: 299 ms, total: 2.19 s
Wall time: 2.18 s

In [7]: %time lst1 = extractSamples(populationSize, sampleSize, [(0, populationSize-1)])
CPU times: user 449 ms, sys: 8.92 ms, total: 458 ms
Wall time: 442 ms

ध्यान दें कि मैंने populationSizeमूल्य को कम कर दिया क्योंकि यह random.sampleसमाधान का उपयोग करते समय उच्च मूल्यों के लिए मेमोरी त्रुटि पैदा करता है ( यहां और यहां पिछले उत्तरों में भी उल्लेख किया गया है )। ऊपर मानों के लिए, हम भी है कि निरीक्षण कर सकते extractSamplesOutperforms random.sampleदृष्टिकोण।

पुनश्च: हालांकि कोर दृष्टिकोण मेरे पहले के उत्तर के समान है , कार्यान्वयन में पर्याप्त संशोधन हैं और साथ ही स्पष्टता में सुधार के साथ दृष्टिकोण भी हैं।


0

एक बहुत ही सरल कार्य जो आपकी समस्या को हल करता है

from random import randint

data = []

def unique_rand(inicial, limit, total):

        data = []

        i = 0

        while i < total:
            number = randint(inicial, limit)
            if number not in data:
                data.append(number)
                i += 1

        return data


data = unique_rand(1, 60, 6)

print(data)


"""

prints something like 

[34, 45, 2, 36, 25, 32]

"""

0

सेट आधारित दृष्टिकोणों के साथ समस्या ("यदि रिटर्न मानों में यादृच्छिक मान, फिर से प्रयास करें") यह है कि टकरावों के कारण उनका रनटाइम अनिर्धारित है (जिसके लिए एक और "पुन: प्रयास" पुनरावृत्ति की आवश्यकता होती है), खासकर जब यादृच्छिक मूल्यों की एक बड़ी राशि वापस आ जाती है। सीमा से।

एक विकल्प जो इस गैर-नियतात्मक रनटाइम के लिए प्रवण नहीं है वह निम्नलिखित है:

import bisect
import random

def fast_sample(low, high, num):
    """ Samples :param num: integer numbers in range of
        [:param low:, :param high:) without replacement
        by maintaining a list of ranges of values that
        are permitted.

        This list of ranges is used to map a random number
        of a contiguous a range (`r_n`) to a permissible
        number `r` (from `ranges`).
    """
    ranges = [high]
    high_ = high - 1
    while len(ranges) - 1 < num:
        # generate a random number from an ever decreasing
        # contiguous range (which we'll map to the true
        # random number).
        # consider an example with low=0, high=10,
        # part way through this loop with:
        #
        # ranges = [0, 2, 3, 7, 9, 10]
        #
        # r_n :-> r
        #   0 :-> 1
        #   1 :-> 4
        #   2 :-> 5
        #   3 :-> 6
        #   4 :-> 8
        r_n = random.randint(low, high_)
        range_index = bisect.bisect_left(ranges, r_n)
        r = r_n + range_index
        for i in xrange(range_index, len(ranges)):
            if ranges[i] <= r:
                # as many "gaps" we iterate over, as much
                # is the true random value (`r`) shifted.
                r = r_n + i + 1
            elif ranges[i] > r_n:
                break
        # mark `r` as another "gap" of the original
        # [low, high) range.
        ranges.insert(i, r)
        # Fewer values possible.
        high_ -= 1
    # `ranges` happens to contain the result.
    return ranges[:-1]

0
import random

sourcelist=[]
resultlist=[]

for x in range(100):
    sourcelist.append(x)

for y in sourcelist:
    resultlist.insert(random.randint(0,len(resultlist)),y)

print (resultlist)

1
Stackoverflow में आपका स्वागत है। कृपया अपना उत्तर बताएं कि यह समस्या को क्यों और कैसे हल करता है ताकि दूसरे आपके उत्तर को आसानी से समझ सकें।
ऑक्टोबस

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

-1

यदि आप यह सुनिश्चित करना चाहते हैं कि जोड़े जा रहे नंबर अद्वितीय हैं, तो आप सेट ऑब्जेक्ट का उपयोग कर सकते हैं

अगर 2.7 या अधिक का उपयोग कर रहे हैं, या नहीं तो सेट मॉड्यूल आयात करें।

जैसा कि दूसरों ने उल्लेख किया है, इसका मतलब है कि संख्या वास्तव में यादृच्छिक नहीं हैं।


-1

minvalऔर बीच में प्रतिस्थापन के बिना पूर्णांकों का नमूना लेने के लिए maxval:

import numpy as np

minval, maxval, n_samples = -50, 50, 10
generator = np.random.default_rng(seed=0)
samples = generator.permutation(np.arange(minval, maxval))[:n_samples]

# or, if minval is 0,
samples = generator.permutation(maxval)[:n_samples]

जुक्स के साथ:

import jax

minval, maxval, n_samples = -50, 50, 10
key = jax.random.PRNGKey(seed=0)
samples = jax.random.shuffle(key, jax.numpy.arange(minval, maxval))[:n_samples]

आप संभावित रूप से बड़ी संख्या में तत्वों का एक परमिटुटेन क्यों उत्पन्न करेंगे और फिर n_samplesउनमें से पहले का चयन करेंगे? इस दृष्टिकोण के पीछे आपका तर्क क्या है? क्या आप बता सकते हैं कि मौजूदा उत्तर की बड़ी संख्या (8 साल पहले उनमें से अधिकांश) की तुलना में आपके दृष्टिकोण के क्या फायदे हैं?
सिरिल

वास्तव में मेरे जवाब में अन्य शीर्ष वोटों के जवाबों की तरह ही जटिलता है और यह तेज है क्योंकि यह सुन्न का उपयोग करता है। अन्य, शीर्ष-वोट वाले तरीकों का उपयोग करते हैं random.shuffle, जो मेरसेन ट्विस्टर का उपयोग करता है, क्विच बहुत अधिक धीमी है, जो कि खट्टे (और शायद जक्स) द्वारा की पेशकश की जाती है। numpy और jax अन्य यादृच्छिक संख्या पीढ़ी एल्गोरिदम के लिए अनुमति देते हैं। jax भी jit-compiling और भेदभाव की अनुमति देता है, जो स्टोकेस्टिक भेदभाव के लिए उपयोगी हो सकता है। एक "संभवतः बड़े" सरणी के संबंध में, कुछ शीर्ष वोट किए गए उत्तर ठीक वही काम करते हैं random.shuffle, जो मुझे नहीं लगता कि किसी रिश्तेदार या पूर्ण अर्थ में पापी है
ग्रैजाइटिस

1
यह निश्चित नहीं है कि " random.shuffleमेर्सन ट्विस्टर का उपयोग करता है" से आपका क्या मतलब है - यह फिशर-येट्स फेरबदल है, जैसा कि कई उत्तरों में उल्लेख किया गया है। इसमें रैखिक समय की जटिलता है, इसलिए यह संभवतः किसी अन्य पुस्तकालय, संख्यात्मक या अन्य द्वारा पेश किए गए एल्गोरिदम की तुलना में समान रूप से धीमा नहीं हो सकता है। यदि सुन्नता तेज है, तो यह केवल इसलिए है क्योंकि यह सी में imlpemented है, लेकिन यह एक विशाल क्रमचय (जो कि मेमोरी में भी फिट नहीं हो सकता है) उत्पन्न करने के लिए वारंट नहीं करता है, केवल इसमें से कुछ तत्वों को चुनने के लिए। तुम्हारे अलावा एक भी जवाब नहीं है जो ऐसा करता है।
किरिल

मेरी क्षमा याचना, मैंने पढ़ा है कि अजगर ने यादृच्छिक रूप से मेरसेन ट्विस्टर का इस्तेमाल किया क्योंकि यह चुभन है। क्या आपके पास एक स्रोत है, इसलिए मैं फिशर येट्स और यादृच्छिक.शफल में भूमिका के बारे में अधिक जान सकता हूं?
ग्रैजाइटिस

यहां पहले से ही दो अलग-अलग उत्तरों पर विकिपीडिया के दो अलग-अलग लिंक हैं। यदि विकिपीडिया आपके लिए एक अच्छा स्रोत नहीं है, तो लेख के अंत में 14 संदर्भ हैं। और फिर गूगल है। क्या उससे मदद हुई? ओह, और randomमॉड्यूल पायथन में लिखा गया है, ताकि आप आसानी से इसके स्रोत (कोशिश random.__file__) को देख सकें ।
किरिल

-3

जीत xp में CLI से:

python -c "import random; print(sorted(set([random.randint(6,49) for i in range(7)]))[:6])"

कनाडा में हमारे पास 6/49 लोटो है। मैं अभी उपरोक्त कोड को लोट्टो.बेट में लपेटता हूं और चलाता हूं C:\home\lotto.batया बस C:\home\lotto

क्योंकि random.randintअक्सर एक संख्या दोहराती है, मैं इसके setसाथ उपयोग करता हूं range(7)और फिर इसे 6 की लंबाई तक छोटा करता हूं ।

कभी-कभी यदि कोई संख्या 2 बार से अधिक दोहराती है तो परिणामी सूची की लंबाई 6 से कम होगी।

EDIT: हालाँकि, random.sample(range(6,49),6)जाने का सही तरीका है।


-3
import random
result=[]
for i in range(1,50):
    rng=random.randint(1,20)
    result.append(rng)

1
क्या आप बता सकते हैं कि यह डुप्लिकेट से कैसे बचा जाता है? यह इस कोड डंप से स्पष्ट नहीं है।
टोबी स्पाइट

यह नहीं है print len(result), len(set(result))। आप यह देखने की उम्मीद करेंगे कि resultहर 1.0851831788708547256608362340568947172111832359638926... × 10^20प्रयास के बाद केवल एक बार अद्वितीय तत्व होंगे ।
जेडी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.