2008-09-23 15 views
8

कल, मैंने this प्रश्न पूछा और वास्तव में कभी जवाब नहीं मिला कि मैं वास्तव में खुश था। मैं सचमुच जानना चाहता हूं कि एन अनूठी यादृच्छिक संख्याओं की सूची कैसे उत्पन्न करें, जैसे कि रूबी जैसे शैली में अत्यधिक अनिवार्य होने के बिना।मैं रूबी/पायथन में इसे कैसे लिखूं? या, क्या आप मेरी LINQ को रूबी/पायथन में अनुवाद कर सकते हैं?

के बाद से मैं कुछ भी नहीं देखा था मैं वास्तव में पसंद है, मैं LINQ में समाधान मैं देख रहा था के लिए लिखा है:


     static void Main(string[] args) 
     { 
      var temp = from q in GetRandomNumbers(100).Distinct().Take(5) select q; 
     } 

     private static IEnumerable GetRandomNumbers(int max) 
     { 
      Random r = new Random(); 
      while (true) 
      { 
       yield return r.Next(max); 
      } 
     } 

आप रूबी के लिए मेरे LINQ का अनुवाद कर सकते हैं? अजगर? कोई अन्य कार्यात्मक प्रोग्रामिंग भाषा?

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

मुझे पता है कि मैं picky, लेकिन मैं वास्तव में इस समस्या के कुछ सुरुचिपूर्ण समाधान देखना चाहता हूं। धन्यवाद!

संपादित करें:
सभी डाउनवॉट क्यों?

मूल रूप से मेरे कोड नमूने में टेक() के बाद अलग() था, जैसा कि कई ने बताया, मुझे खाली सूची के साथ छोड़ सकता है। मैंने उस क्रम को बदल दिया है जिसमें उन तरीकों को प्रतिबिंबित करने के लिए बुलाया गया है जो मेरा पहला मतलब था।

माफी:
मुझे बताया गया है इस पोस्ट के रूप में नहीं बल्कि दंभपूर्ण बारे में जाना। मैं यह इंगित करने की कोशिश नहीं कर रहा था कि LINQ रूबी/पायथन से बेहतर है; या मेरा समाधान हर किसी के मुकाबले ज्यादा बेहतर है। मेरा इरादा सिर्फ यह जानने के लिए है कि रुबी में यह कैसे करें (कुछ बाधाओं के साथ)। मुझे खेद है अगर मैं एक झटका के रूप में आया था।

+0

बस इसलिए हम इस पर स्पष्ट कर रहे हैं: भले ही अजगर कुछ कार्यात्मक निर्माणों, सूची comprehensions की तरह है, यह वास्तव में एक कार्यात्मक भाषा नहीं है, और यह एक नहीं है समस्या जो आप आसानी से पाइथन में एक वास्तविक कार्यात्मक शैली में हल करेंगे। –

+0

मुझे आवश्यकताएं नहीं मिलती हैं। क्या यह एन मान लेना है और उस सेट में अलग-अलग मानों का पता लगाना है? या यह कुछ आकार के एक सेट का पता लगाने के लिए है जिसमें एन विशिष्ट मान हैं? –

+0

यदि आप (5) लेते हैं और फिर अलग ... आप 1 नंबर के साथ हवादार हो सकते हैं। –

उत्तर

5

रूबी में:

a = (0..100).entries.sort_by {rand}.slice! 0, 5 

अद्यतन: यहाँ एक अलग तरीका है: एक = (0 ... 100) .entries.sort_by {रैंड} [0 ... 5]

संपादित करें:

और रूबी 1.9 में आप यह कर सकते हैं:

Array(0..100).sample(5) 
0

संख्यात्मक अजगर के साथ पायथन:

from numpy import * 
a = random.random_integers(0, 100, 5) 
b = unique(a) 

देखा! निश्चित रूप से आप एक कार्यात्मक प्रोग्रामिंग शैली में कुछ ऐसा कर सकते हैं लेकिन ... क्यों?

+0

क्योंकि यह इटरेटर का उपयोग नहीं करता है और स्मृति में सभी पूर्णांक स्टोर करता है। –

2

मैं 'यादृच्छिक' मॉड्यूल का उपयोग करके सबसे सरल समाधान छोड़ दूंगा क्योंकि मैं इसे लेता हूं जो वास्तव में आपके बाद नहीं है। यहाँ मैं क्या लगता है कि तुम अजगर में देख रहे है:

>>> import random 
>>> 
>>> def getUniqueRandomNumbers(num, highest): 
...  seen = set() 
...  while len(seen) < num: 
...   i = random.randrange(0, highest) 
...   if i not in seen: 
...    seen.add(i) 
...    yield i 
... 
>>> 

आप को दिखाने के लिए कि यह कैसे काम करता है:

>>> list(getUniqueRandomNumbers(10, 100)) 
[81, 57, 98, 47, 93, 31, 29, 24, 97, 10] 
13
>>> import random 
>>> print random.sample(xrange(100), 5) 
[61, 54, 91, 72, 85] 

इस रेंज 0 — 99 में 5 अद्वितीय मान उपज चाहिए। xrange ऑब्जेक्ट मूल्यों को अनुरोध के रूप में उत्पन्न करता है ताकि नमूने वाले मानों के लिए कोई स्मृति उपयोग न हो।

+3

xrange() वास्तव में जनरेटर का उपयोग नहीं करता है। यह एक नकली सूची है। जनरेटर अनुक्रम नहीं हैं और अनुक्रमित नहीं किए जा सकते हैं, इसलिए random.sample() अगर यह एक विफल हो जाएंगे। –

+0

सही, ज़ाहिर है, धन्यवाद। सही किया। –

+0

नमूने अद्वितीय क्यों होंगे? विशिष्टता को आश्वस्त करने के लिए किसी भी प्रकार का फ़िल्टर प्रतीत नहीं होता है। –

-1

मैं वास्तव में आपके LINQ को नहीं पढ़ सकता, लेकिन मुझे लगता है कि आप 100 तक 5 यादृच्छिक संख्याएं प्राप्त करने का प्रयास कर रहे हैं और फिर डुप्लिकेट हटा दें।

यहाँ कि के लिए एक समाधान है:

def random(max) 
    (rand * max).to_i 
end 

a = [] 
while(a.size < 5) 
    a << random(100) 
    a = a & a 
end 

अब, यह एक हो सकता है:

def random(max) 
    (rand * max).to_i 
end 

# Get 5 random numbers between 0 and 100 
a = (1..5).inject([]){|acc,i| acc << random(100)} 
# Remove Duplicates 
a = a & a 

लेकिन शायद आप वास्तव में 0 और 100 के बीच 5 अलग यादृच्छिक संख्या के लिए देख रहे हैं जो मामले में "बहुत अधिक लूप नहीं" की अपनी भावना का उल्लंघन करें, लेकिन संभवतः ले लो और डिस्टिंट सिर्फ आपके से लूपिंग छुपा रहे हैं। थोड़ी देर लूप को छिपाने के लिए संख्याओं को जोड़ने के लिए पर्याप्त आसान होगा।

+0

सच: मुझे एहसास है कि ले लो और डिस्टिंट शायद दृश्यों के पीछे लूपिंग कर रहे हैं। मेरा मतलब था कि कोई लूप नहीं था जिसे आपको लिखना होगा ... फिर भी मैं आपके दूसरे समाधानों की तरह करता हूं। धन्यवाद! –

+0

'(रैंड * अधिकतम) .to_i' को 'रैंड अधिकतम' – user102008

3

हम्म ... कैसे (अजगर) के बारे में:

s = set() 
while len(s) <= N: s.update((random.random(),)) 
+0

के रूप में लिखा जाना चाहिए क्यों set.add का उपयोग नहीं करें? –

+0

मेरा बुरा! इसे इंगित करने के लिए धन्यवाद ;-) –

2

यहाँ एक और रूबी समाधान है:

a = (1..5).collect { rand(100) } 
a & a 

मुझे लगता है, अपने LINQ बयान के साथ, अलग डुप्लिकेट निकालने के बाद 5 पहले से ही ले लिया गया है , इसलिए आपको 5 वापस पाने की गारंटी नहीं है। यदि मैं गलत हूं, तो कोई मुझे सही कर सकता है।

+0

हां, मैं इसके बारे में भी चिंतित था। हालांकि, मैं अभी तक 5 से कम तत्वों के साथ एक सरणी उत्पन्न करने में सक्षम नहीं हूं। इसका मतलब यह नहीं है कि यह हो सकता है। सबसे खराब स्थिति हालांकि, मैं अलग() beofre टेक(), सही कह सकता है? –

0
import random 

def makeRand(n): 
    rand = random.Random() 
    while 1: 
     yield rand.randint(0,n) 
    yield rand.randint(0,n)  

gen = makeRand(100)  
terms = [ gen.next() for n in range(5) ] 

print "raw list" 
print terms 
print "de-duped list" 
print list(set(terms)) 

# produces output similar to this 
# 
# raw list 
# [22, 11, 35, 55, 1] 
# de-duped list 
# [35, 11, 1, 22, 55] 
0

ठीक है, पहले आप पाइथन में LINQ को फिर से लिखते हैं। फिर अपने समाधान एक एक लाइनर :)

from random import randrange 

def Distinct(items): 
    set = {} 
    for i in items: 
     if not set.has_key(i): 
      yield i 
      set[i] = 1 

def Take(num, items): 
    for i in items: 
     if num > 0: 
      yield i 
      num = num - 1 
     else: 
      break 

def ToArray(items): 
    return [i for i in items] 

def GetRandomNumbers(max): 
    while 1: 
     yield randrange(max) 

print ToArray(Take(5, Distinct(GetRandomNumbers(100)))) 

आप एक मॉड्यूल LINQ.py कहा जाता है में सब से ऊपर सरल तरीके डाल, तो आप अपने मित्रों को प्रभावित कर सकते हैं।

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

+0

अच्छा। बस एक छोटी टिप्पणी: आपको Distince और ToArray में हैश के बजाय एक सेट() का उपयोग करना चाहिए()। – olt

2

संपादित करें: ठीक है, बस मस्ती के लिए, एक छोटा और तेज़ वाला (और अभी भी इटरेटर का उपयोग कर रहा है)।

def getRandomNumbers(max, size) : 
    pool = set() 
    return ((lambda x : pool.add(x) or x)(random.randrange(max)) for x in xrange(size) if len(a) < size) 

print [x for x in gen(100, 5)] 
[0, 10, 19, 51, 18] 

हाँ, मुझे पता है, एक-लाइनर्स प्रेमियों पर्ल के लिए छोड़ दिया जाना चाहिए, लेकिन मुझे लगता है कि यह एक काफी शक्तिशाली है यह नहीं है?

पुरानी यहाँ संदेश:

मेरे भगवान, कैसे जटिल है कि सभी है!चलो pythonic हो:

import random 
def getRandomNumber(max, size, min=0) : 
    # using() and xrange = using iterators 
    return (random.randrange(min, max) for x in xrange(size)) 

print set(getRandomNumber(100, 5)) # set() removes duplicates 
set([88, 99, 29, 70, 23]) 

का आनंद लें

संपादित करें: जैसा कि टिप्पणीकारों देखा, इस सवाल के कोड का एक सटीक अनुवाद है।

समस्या हम सूची तैयार, बहुत कम डेटा में जिसके परिणामस्वरूप के बाद डुप्लिकेट को निकाल कर मिला बचने के लिए आप एक और तरीका चुन सकते हैं:

def getRandomNumbers(max, size) : 
    pool = [] 
    while len(pool) < size : 
     tmp = random.randrange(max) 
     if tmp not in pool : 
      yield pool.append(tmp) or tmp 

print [x for x in getRandomNumbers(5, 5)] 
[2, 1, 0, 3, 4] 
+0

यदि आपके पास डुप्लिकेट हटा दिया गया है, तो क्या आप वांछित से कम मूल्यों के साथ समाप्त नहीं होंगे? –

+0

हां, लेकिन उन्होंने अपने प्रश्न में ऐसा ही किया, इसलिए यह एक सटीक अनुवाद है। यही पूछा जाता है: एक अनुवाद। –

+0

उसने नहीं किया -। टेक (5)। डिस्टिंट कॉल के बाद होता है, इसलिए पहले से ही बिना अनुक्रमित अनुक्रम से 5 आइटम खींचेगा। – Brian

0

यहाँ अजगर करने के लिए अपने समाधान से एक लिप्यंतरण है।

पहला, एक जेनरेटर जो यादृच्छिक संख्या बनाता है। यह बहुत पाइथोनिक नहीं है, लेकिन यह आपके नमूना कोड के साथ एक अच्छा मैच है।

>>> import random 
>>> def getRandomNumbers(max): 
...  while True: 
...    yield random.randrange(0,max) 

यहाँ एक ग्राहक पाश है कि 5 अलग-अलग मान का एक सेट जमा करता है। यह फिर से - सबसे पायथनिक कार्यान्वयन नहीं है।

>>> distinctSet= set() 
>>> for r in getRandomNumbers(100): 
...  distinctSet.add(r) 
...  if len(distinctSet) == 5: 
...    break 
... 
>>> distinctSet 
set([81, 66, 28, 53, 46]) 

यह स्पष्ट नहीं है कि तुम क्यों यादृच्छिक संख्या के लिए एक जनरेटर का उपयोग करना चाहते हैं - कि कुछ चीजें हैं जो इतना आसान है कि एक जनरेटर इसे सरल नहीं है में से एक है।

एक और अधिक pythonic संस्करण कुछ इस हो सकता है:

distinctSet= set() 
while len(distinctSet) != 5: 
    distinctSet.add(random.randrange(0,100)) 

आवश्यकताओं 5 मूल्यों उत्पन्न करने के लिए है, तो जैसे

distinctSet= set([random.randrange(0,100) for i in range(5) ]) 
0

कुछ हो सकता है कि इस सूट कर रहे हैं और उन 5 के बीच अलग पाते हैं अपने जरूरतों और थोड़ा और linqish देखो:

from numpy import random,unique 

def GetRandomNumbers(total=5): 
    while True: 
     yield unique(random.random(total*2))[:total] 

randomGenerator = GetRandomNumbers() 

myRandomNumbers = randomGenerator.next() 
+0

पोस्ट करने के बाद से मानक लाइब्रेरी के साथ काम नहीं करता है। –

0

यहां एक और अजगर बनाम है n, आपके सी # कोड की संरचना से अधिक निकटता से मेल खाता है। अलग-अलग परिणाम देने के लिए कोई अंतर्निहित नहीं है, इसलिए मैंने ऐसा करने के लिए एक फ़ंक्शन जोड़ा है।

import itertools, random 

def distinct(seq): 
    seen=set() 
    for item in seq: 
     if item not in seen: 
      seen.add(item) 
      yield item 

def getRandomNumbers(max): 
    while 1: 
     yield random.randint(0,max) 

for item in itertools.islice(distinct(getRandomNumbers(100)), 5): 
    print item 
संबंधित मुद्दे

 संबंधित मुद्दे