我如何用Ruby/Python编写这个?或者,你能把我的LINQ翻译成Ruby/Python吗?
昨天,我问了一个问题,但从来没有得到一个我真正满意的答案。我真的很想知道如何使用Ruby之类的函数式语言生成一个由N个唯一随机数组成的列表,而不必在样式上非常必要 因为我没有看到任何我真正喜欢的东西,所以我在LINQ中编写了我正在寻找的解决方案:我如何用Ruby/Python编写这个?或者,你能把我的LINQ翻译成Ruby/Python吗?,python,ruby,linq,functional-programming,Python,Ruby,Linq,Functional Programming,昨天,我问了一个问题,但从来没有得到一个我真正满意的答案。我真的很想知道如何使用Ruby之类的函数式语言生成一个由N个唯一随机数组成的列表,而不必在样式上非常必要 因为我没有看到任何我真正喜欢的东西,所以我在LINQ中编写了我正在寻找的解决方案: static void Main(string[] args) { var temp = from q in GetRandomNumbers(100).Distinct().Take(5) se
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翻译成Ruby吗?python还有其他函数式编程语言吗
注意:请尽量不要使用太多的循环和条件-否则解决方案很简单。另外,我更希望看到一个解决方案,在这个解决方案中,您不必生成一个比N大得多的数组,这样您就可以删除重复项并将其修剪为N
我知道我很挑剔,但我真的很想看到一些优雅的解决方案。
谢谢
编辑:为什么会有这么多的反对票 最初,我的代码示例在Take()后面有Distinct(),正如许多人指出的那样,这可能会给我留下一个空列表。我改变了调用这些方法的顺序,以反映我最初的意思 道歉:
有人告诉我,这篇文章给人的印象是相当势利。我并不是想暗示LINQ比Ruby/Python更好;或者我的解决方案比其他人的好得多。我的目的只是学习如何在Ruby中实现这一点(有一定的限制)。如果我给人的印象是一个混蛋,我很抱歉。Python与数字Python:
from numpy import *
a = random.random_integers(0, 100, 5)
b = unique(a)
瞧!当然你可以在函数式编程风格中做类似的事情,但是。。。为什么?我将放弃使用“随机”模块的最简单解决方案,因为我认为这不是您真正想要的。以下是我认为您在Python中需要的内容:
>>> 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
...
>>>
这将在
0-99范围内产生5个唯一值。xrange
对象根据请求生成值,因此没有内存用于未采样的值。我无法真正读取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
def随机(最大值)
(兰特*最大值)至
结束
#得到5个介于0和100之间的随机数
a=(1..5).injection([]){| acc,i | accHmm.(Python)怎么样:
s=set()
而Ruby中的len(s):
a = (0..100).entries.sort_by {rand}.slice! 0, 5
更新:这里有一种稍微不同的方式:
a=(0…100).entries.sort_by{rand}[0…5]
编辑:
在Ruby 1.9中,您可以这样做:
Array(0..100).sample(5)
下面是另一个Ruby解决方案:
a = (1..5).collect { rand(100) }
a & a
我认为,使用您的LINQ语句,Distinct将在已获取5个后删除重复项,因此您不能保证获得5个。但是,如果我错了,有人可以纠正我。首先,您用Python重写LINQ。然后,您的解决方案是一行:)
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.py的模块中,你就能给你的朋友留下深刻的印象
(免责声明:当然,这实际上并不是在Python中重写LINQ。人们错误地认为LINQ只是一堆琐碎的扩展方法和一些新语法。然而,LINQ真正高级的部分是自动生成SQL,因此在查询数据库时,实现Distinct()的是数据库。)而不是客户端。)编辑:好的,只是为了好玩,更短更快(仍然使用迭代器)
享受
编辑:正如评论员所注意到的,这是问题代码的精确翻译
为了避免在生成列表后删除重复项导致数据太少的问题,您可以选择另一种方式:
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]
def GetRandomNumber(最大,大小):
池=[]
而len(池)<大小:
tmp=随机随机随机范围(最大值)
如果tmp不在池中:
收益池追加(tmp)或tmp
在getRandomNumbers(5,5)中打印[x代表x]
[2, 1, 0, 3, 4]
这里是从您的解决方案到Python的音译
首先,是一个生成随机数的生成器。这不是很像Python,但它与您的示例代码非常匹配
>>> 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])
不清楚为什么要使用随机数生成器——这是为数不多的几件简单到生成器无法简化的事情之一
更具python风格的版本可能类似于:
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()
这是另一个python版本,与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
在Ruby 1.9中:
Array(0..100).sample(5)
xrange()实际上不使用生成器。它是一个假列表。生成器不是序列,不能被索引,因此random.sample()将失败,如果它是一个。为什么样本是唯一的?似乎没有任何类型的过滤器来确保唯一性。random.sample()函数本身就可以做到这一点。“返回从填充序列中选择的唯一元素的k长度列表"。所以我们很清楚这一点:尽管Python有一些函数构造,比如列表理解,但它实际上不是一种函数式语言,而且这不是一个用Python真正的函数式风格很容易解决的问题。我不明白这些要求。是取N个值并在该集中定位不同的值?还是定位不同的值一个有N个不同值的大小的集合?如果你取(5),然后取不同值…你可能会得到1个数字。@David:是的,我刚刚改变了它们的顺序。谢谢!我敢打赌这意味着LINQ是如此明显的优越,没有人能生产出符合你崇高的“优雅”标准的Ruby或Python.只是猜测而已.这个问题很蹩脚,但不是那样
>>> import random
>>> def getRandomNumbers( max ):
... while True:
... yield random.randrange(0,max)
>>> distinctSet= set()
>>> for r in getRandomNumbers( 100 ):
... distinctSet.add( r )
... if len(distinctSet) == 5:
... break
...
>>> distinctSet
set([81, 66, 28, 53, 46])
distinctSet= set()
while len(distinctSet) != 5:
distinctSet.add( random.randrange(0,100) )
distinctSet= set( [random.randrange(0,100) for i in range(5) ] )
from numpy import random,unique
def GetRandomNumbers(total=5):
while True:
yield unique(random.random(total*2))[:total]
randomGenerator = GetRandomNumbers()
myRandomNumbers = randomGenerator.next()
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
Array(0..100).sample(5)