كيف أكتب هذا في روبي/الثعبان ؟ أو يمكنك ترجمة LINQ إلى روبي/الثعبان ؟
-
02-07-2019 - |
سؤال
أمس طلبت هذا سؤال لم نجد جوابا كنت سعيدا حقا مع.أود حقا أن أعرف كيفية إنشاء قائمة 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 لإخفاء أثناء الحلقة.