我从SICP学到了很多方案,但现在对普通的lisp更感兴趣.我知道普通的lisp fold是reduce,有左或右折叠的特殊参数,但是相当于unfold什么?谷歌搜索没有多大帮助.事实上,我得到的印象是没有展开???
Fold(又名reduce)被认为是一个非常重要的高阶函数.Map可以表示fold(见这里).但这对我来说听起来比实际更具有学术性.典型的用途可能是获得总和,产品或数字的最大值,但这些函数通常接受任意数量的参数.那么为什么写的(fold + 0 '(2 3 5))时候(+ 2 3 5)工作正常.我的问题是,在什么情况下使用最简单或最自然fold?
我有一个链接列表,想知道连接的路径/周期.
我的链接看起来像这样:
[[0, 3], [1, 0], [3, 1]]
Run Code Online (Sandbox Code Playgroud)
我希望答案是这样的循环(或任何其他匹配循环):
[0,3,1]
Run Code Online (Sandbox Code Playgroud)
因此,您获取第一个子列表的第一个元素,然后您获取第二个元素,并查找以此元素开头的下一个子列表,然后重新开始.
有一种优雅的方式来实现这一目标吗?我尝试了reduce函数,但是链接必须以链接匹配的方式进行排序.
1我试图制作一个无限制因子函数(只是出于好奇.)这适用于大型n(尝试高达100000并且它似乎工作,虽然我无法检查输出值的正确性,因为,它是大!)
(BigInt(1) to n).reduceRight(_*_)
Run Code Online (Sandbox Code Playgroud)
但我担心整个BigInt(1) to n范围可能都在记忆中,而我只是逐个元素地需要它reduceRight.看看Scala的标准库代码看起来BigInt(1) to n实际上是输出整个Range而不是懒惰Stream但我发现Stream.range我可以这样使用(注意n+1,流范围是独占的)
Stream.range[BigInt](BigInt(1), BigInt(n+1)).reduceRight(_*_)
Run Code Online (Sandbox Code Playgroud)
它适用于n=10000(由于某种原因,它需要更长的时间!这让我觉得也许正常的范围实际上也是一个Stream?)但是因为n=100000我得到这个堆栈溢出
java.lang.StackOverflowError
at java.math.BigInteger.add(Unknown Source)
at scala.math.BigInt.$plus(BigInt.scala:161)
at scala.math.Numeric$BigIntIsIntegral$class.plus(Numeric.scala:28)
at scala.math.Numeric$BigIntIsIntegral$.plus(Numeric.scala:40)
at scala.math.Numeric$BigIntIsIntegral$.plus(Numeric.scala:40)
at scala.math.Numeric$Ops.$plus(Numeric.scala:208)
at scala.collection.immutable.Stream$$anonfun$range$1.apply(Stream.scala:695)
at scala.collection.immutable.Stream$$anonfun$range$1.apply(Stream.scala:695)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:634)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:626)
at scala.collection.LinearSeqOptimized$class.reduceRight(LinearSeqOptimized.scala:130)
at scala.collection.immutable.Stream.reduceRight(Stream.scala:47)
at scala.collection.LinearSeqOptimized$class.reduceRight(LinearSeqOptimized.scala:131)
at scala.collection.immutable.Stream.reduceRight(Stream.scala:47)
at scala.collection.LinearSeqOptimized$class.reduceRight(LinearSeqOptimized.scala:131)
at scala.collection.immutable.Stream.reduceRight(Stream.scala:47)
...
Run Code Online (Sandbox Code Playgroud)
很明显,reduceRight就是这样称呼自己
reduceRight(reduceRight(first, second, op), third, op)...
Run Code Online (Sandbox Code Playgroud)
因此堆栈溢出.我假设它不是尾部调用优化的,因为它首先减少然后在返回值之前运行,因此无法进行优化.那我怎么能解决这个问题呢?我是否应该放弃功能方法并针对自定义命令式代码进行减少?
让我感到非常奇怪的是,虽然使用流几乎相同(BigInt(1) …
我必须保存并加载一个cython类实例.我的cython类是以及几种方法:
import numpy as np
cimport numpy as np
cimport cython
cdef class Perceptron_avg_my:
cdef int wlen,freePos
cdef np.ndarray w,wtot,wac,wtotc #np.ndarray[np.int32_t]
cdef np.ndarray wmean #np.ndarray[np.float32_t]
cdef public dict fpos
def __cinit__(self,np.int64_t wlen=4*10**7):
self.fpos= dict()
self.freePos=1
self.wlen=wlen
self.w=np.zeros(wlen,np.int32)
self.wtot=np.zeros(wlen,np.int32)
self.wac=np.zeros(wlen,np.int32)
self.wtotc=np.zeros(wlen,np.int32)
self.wmean=np.zeros(wlen,np.float32)
cpdef evaluate_noavg(self,list f):
cdef np.ndarray[np.int32_t] w = self.w
cdef dict fpos = self.fpos
cdef bytes ff
cdef int i
cdef long int score=0
for ff in f:
i=fpos.get(ff,0)
if i != 0:
score += w[i]
return score
Run Code Online (Sandbox Code Playgroud)
我在考虑使用cPickle模块.我明白我必须实现一个__reduce __(自我)方法但是我有一些问题需要找到一个例子并且很好地理解文档 …
我正在看这个使用reduce()函数的例子.
function add(runningTotal, currentValue) {
return runningTotal + currentValue;
}
var nums = [1,2,3,4,5,6,7,8,9,10];
var sum = nums.reduce(add);
print(sum); // displays 55
Run Code Online (Sandbox Code Playgroud)
你能告诉我一些使用reduce()的其他例子 - 我不确定我是否完全遵循它的工作原理.
谢谢
我认为自己是一个经验丰富的numpy用户,但我无法找到解决以下问题的方法.假设有以下数组:
# sorted array of times
t = numpy.cumsum(numpy.random.random(size = 100))
# some values associated with the times
x = numpy.random.random(size=100)
# some indices into the time/data array
indices = numpy.cumsum(numpy.random.randint(low = 1, high=10,size = 20))
indices = indices[indices <90] # respect size of 100
if len(indices) % 2: # make number of indices even
indices = indices[:-1]
# select some starting and end indices
istart = indices[0::2]
iend = indices[1::2]
Run Code Online (Sandbox Code Playgroud)
我现在想要的是在x给定由istart和表示的区间的情况下减少值数组iend.即
# e.g. …Run Code Online (Sandbox Code Playgroud) 假设我有以下对象数组:
var arr = [
{"name": "John", "score": "8.8"},
{"name": "John", "score": "8.6"},
{"name": "John", "score": "9.0"},
{"name": "John", "score": "8.3"},
{"name": "Tom", "score": "7.9"}
];
var count = 0;
var avgScore = arr.reduce(function (sum,person) {
if (person.name == "John") {
count+=1;
return sum + parseFloat(person.score);
}
return sum;
},0)/count);
Run Code Online (Sandbox Code Playgroud)
问题:有没有办法在不创建全局计数变量的情况下计算"John"的平均分数.理想情况下,计数将在arr.reduce中的匿名函数内部.
当数组中的值与索引相同时,代码将返回数组中的最低索引.如果没有匹配,我应该返回-1.例如:
indexEqualsValue([-8,0,2,5])
output: 2 //array[2] == 2
indexEqualsValue([-1,0,3,6])
output: -1 //no matches
Run Code Online (Sandbox Code Playgroud)
当没有匹配或者数组的长度为零时,代码可以工作,但在其他时候则不行.我认为问题是我的if语句中的第一个条件.我不一定想要一个答案,更多关于我应该检查/重写的提示.
谢谢!
function indexEqualsValue(a) {
return a.reduce((acc, currV, currI) => {
if (currI === currV) {
return currV;
}
return -1;
}, 0);
}
Run Code Online (Sandbox Code Playgroud) 我想将此对象简化为包含产品名称和平均价格的对象.最快的方法是什么?
var foo = { group1: [
{
name: "one",
price: 100
},
{
name: "two",
price: 100
}],
group2: [
{
name: "one",
price: 200
},
{
name: "two",
price: 200
}],
group3: [
{
name: "one",
price: 300
},
{
name: "two",
price: 300
}]
}
Run Code Online (Sandbox Code Playgroud)
导致
var foo2 = [{
name: 'one',
price: 200
},{
name: 'two',
price: 200
}];
Run Code Online (Sandbox Code Playgroud)
谢谢!