كيف أكتب هذا في روبي/الثعبان ؟ أو يمكنك ترجمة LINQ إلى روبي/الثعبان ؟

StackOverflow https://stackoverflow.com/questions/122033

سؤال

أمس طلبت هذا سؤال لم نجد جوابا كنت سعيدا حقا مع.أود حقا أن أعرف كيفية إنشاء قائمة N فريدة من نوعها أرقام عشوائية باستخدام لغة وظيفية مثل روبي دون الحاجة إلى أن تكون غاية حتمية في الاسلوب.

منذ أنا لم أرى أي شيء أنا حقا أحب كتبت الحل كنت أبحث عنه في 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 إلى روبي ؟ الثعبان ؟ أي البرمجة الوظيفية اللغة ؟

ملاحظة: أرجوك حاول أن لا تستخدم الكثير من الحلقات الشرطية - وإلا فإن الحل هو تافهة.كما أنني أفضل أن أرى الحل حيث لم يكن لديك إلى توليد مجموعة أكبر بكثير من N بحيث يمكنك فقط إزالة التكرارات وتقليم عليه N.

أعرف أن من الصعب إرضاءه ، ولكن أود حقا أن نرى بعض أنيقة حلول لهذه المشكلة.وذلك بفضل!

تحرير:
لماذا كل downvotes?

أصلا بلدي نموذج التعليمات البرمجية قد متميزة() بعد أخذ() والذي كثيرة كما أشار إلى أن ترك لي مع قائمة فارغة.لقد تغير ترتيب هذه الأساليب تسمى تعكس ما قصدته في المقام الأول.

اعتذار:
لقد قلت هذا المنصب جاء عبر غرورا.لم أكن أحاول أن يعني أن ينق أفضل من روبي/الثعبان;أو أن الحل هو أفضل بكثير من أي شخص آخر.هدفي هو أن تتعلم كيف تفعل هذا (مع بعض القيود) في روبي.أنا آسف إذا جئت عبر أحمق.

هل كانت مفيدة؟

المحلول

في روبي:

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

التحديث:هنا هو طريقة مختلفة قليلا:a = (0...100).الإدخالات.sort_by{راند}[0...5]

تحرير:

و في روبي 1.9 يمكنك القيام بذلك:

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

نصائح أخرى

>>> import random
>>> print random.sample(xrange(100), 5)
[61, 54, 91, 72, 85]

هذا ينبغي أن تسفر 5 قيم فريدة في نطاق 0 — 99.على xrange كائن يولد القيم المطلوبة حتى لا يتم استخدام الذاكرة من أجل القيم التي ليست عينات.

همم...ماذا عن (الثعبان):

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

أنا لن تتخلى عن أبسط الحلول باستخدام 'عشوائية' وحدة منذ أعتبر هذا ليس حقا ما كنت بعد.وهنا ما أعتقد أنك تبحث في بايثون:

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

هنا آخر روبي الحل:

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

أعتقد مع LINQ بيان متميزة من شأنها إزالة التكرارات بعد 5 اتخذت بالفعل, لذلك لم تكن مضمونة للحصول على 5 مرة أخرى.شخص يمكن تصحيح لي إذا كنت مخطئا ، على الرغم من.

تحرير :حسنا, فقط من أجل المتعة ، أقصر وأسرع واحد (و لا تزال تستخدم التكرار).

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]

في روبي 1.9:

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

بيثون مع الرقمية بايثون:

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

فويلا!متأكد من أنك يمكن أن تفعل شيئا من هذا القبيل في البرمجة الوظيفية أسلوب ولكن...لماذا ؟

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]

حسنا, أولا يجب كتابة 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, ومع ذلك, هو آلي SQL جيل حتى عندما كنت الاستعلام عن قاعدة البيانات هو قاعدة البيانات التي تطبق متميزة() بدلا من جانب العميل.)

هنا الحروف من حل بيثون.

أول مولد كهربائي على أن يخلق أرقام عشوائية.هذا ليس جدا Pythonic, لكنه مباراة جيدة مع نموذج التعليمات البرمجية.

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

هنا العميل حلقة يجمع مجموعة من 5 قيم مميزة.هذا هو -- مرة أخرى -- لا أكثر Pythonic التنفيذ.

>>> 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 قيم تجد متميزة بين أولئك 5, ثم شيء من هذا القبيل

distinctSet= set( [random.randrange(0,100) for i in range(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()

هنا آخر نسخة بايثون أكثر مواءمة هيكل من التعليمات البرمجية C#.ليس هناك مدمج من أجل إعطاء نتائج متميزة ، حتى لقد أضاف وظيفة للقيام بذلك.

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

لا أستطيع قراءة LINQ, ولكن أعتقد أنك تحاول الحصول على 5 أرقام عشوائية تصل إلى 100 ثم إزالة التكرارات.

هنا الحل لذلك:

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

ولكن ربما كنت فعلا تبحث عن 5 متميزة أرقام عشوائية بين 0 و 100.في هذه الحالة:

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

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

الآن هذا قد يخالف إحساسك "ليس الكثير من الحلقات ،" ولكن يفترض اتخاذ ومتميزة هي مجرد إخفاء حلقات من أنت.سيكون من السهل بما فيه الكفاية فقط إضافة أساليب Enumerable لإخفاء أثناء الحلقة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top