我在Python中实现了一个基于生成器的扫描程序,它将字符串标记为表单的元组(标记类型,标记值):
for token in scan("a(b)"):
print token
Run Code Online (Sandbox Code Playgroud)
会打印
("literal", "a")
("l_paren", "(")
...
Run Code Online (Sandbox Code Playgroud)
下一个任务意味着解析令牌流,为此,我需要能够从当前的一个项目前面查看一个项目,而不必将指针向前移动.事实上,迭代器和生成器不能一次提供完整的项目序列,但是每个项目根据需要使得前瞻与列表相比有点棘手,因为除非__next__()被调用,否则下一个项目是未知的.
什么可以直接实现基于生成器的前瞻看起来像?目前我正在使用一种解决方法,这意味着从生成器中生成一个列表:
token_list = [token for token in scan(string)]
Run Code Online (Sandbox Code Playgroud)
然后很容易通过以下方式实现前瞻:
try:
next_token = token_list[index + 1]
except: IndexError:
next_token = None
Run Code Online (Sandbox Code Playgroud)
当然这只是工作正常.但是考虑到这一点,我的第二个问题就出现了:首先是否真的需要制造scan()发电机?
我正在寻找一个可迭代i和大小的函数,n并产生长度n为连续值的元组i:
x = [1,2,3,4,5,6,7,8,9,0]
[z for z in TheFunc(x,3)]
Run Code Online (Sandbox Code Playgroud)
给
[(1,2,3),(4,5,6),(7,8,9),(0)]
Run Code Online (Sandbox Code Playgroud)
标准库中是否存在这样的功能?
如果它作为标准库的一部分存在,我似乎无法找到它并且我已经没有用于搜索的术语.我可以自己写,但我宁愿不写.
在一台PC上运行CMake时,CMake默认生成NMake文件.另一方面,它生成一个Visual Studio项目.
我知道我可以通过添加-G "NMake Makefiles"到我的CMake语句的末尾来覆盖默认值,但我想知道为什么它默认为一个上的Visual Studio项目和另一个上的NMake文件.
我正在使用生成器和Bluebird编写代码,我有以下内容:
var async = Promise.coroutine;
function Client(request){
this.request = request;
}
Client.prototype.fetchCommentData = async(function* (user){
var country = yield countryService.countryFor(user.ip);
var data = yield api.getCommentDataFor(user.id);
var notBanned = yield authServer.authenticate(user.id);
if (!notBanned) throw new AuthenticationError(user.id);
return {
country: country,
comments: data,
notBanned: true
};
});
Run Code Online (Sandbox Code Playgroud)
但是,这有点慢,我觉得我的应用程序等待I/O太多而且它不是并行的.如何提高应用程序的性能?
总响应时间为800 countryFor+ 400 getCommentDataFor+ + 600,authenticate因此总共1800ms这是很多.
[注意:我在Go中阅读了Python风格的生成器,这不是它的重复.]
在Python/Ruby/JavaScript/ECMAScript 6中,可以使用yield语言提供的关键字编写生成器函数.在Go中,可以使用goroutine和channel模拟它.
以下代码显示了如何实现置换函数(abcd,abdc,acbd,acdb,...,dcba):
// $src/lib/lib.go
package lib
// private, starts with lowercase "p"
func permutateWithChannel(channel chan<- []string, strings, prefix []string) {
length := len(strings)
if length == 0 {
// Base case
channel <- prefix
return
}
// Recursive case
newStrings := make([]string, 0, length-1)
for i, s := range strings {
// Remove strings[i] and assign the result to newStringI
// Append strings[i] to newPrefixI
// Call the recursive case
newStringsI …Run Code Online (Sandbox Code Playgroud) 我正在尝试将类型添加到返回生成器的方法中。每当我使用指定的返回类型运行此程序时,都会引发 TypeError。
添加引号或删除输入可修复错误,但这似乎是 hack。当然,有一种正确的方法可以做到这一点。
def inbox_files(self) -> "Generator[RecordsFile]":
...
# OR
def inbox_files(self):
...
Run Code Online (Sandbox Code Playgroud)
from typing import Generator, List
from .records_file import RecordsFile
Class Marshaller:
...
def inbox_files(self) -> Generator[RecordsFile]:
return self._search_directory(self._inbox)
def _search_directory(self, directory: str) -> RecordsFile:
for item_name in listdir(directory):
item_path = path.join(item_name, directory)
if path.isdir(item_path):
yield from self._search_directory(item_path)
elif path.isfile(item_path):
yield RecordsFile(item_path)
else:
print(f"[WARN] Unknown item found: {item_path}")
Run Code Online (Sandbox Code Playgroud)
生成以下堆栈跟踪:
Traceback (most recent call last):
File "./bin/data_marshal", line 8, in <module>
from src.app import App
File "./src/app.py", line …Run Code Online (Sandbox Code Playgroud) 我想构造一个像随机数生成器一样工作的对象,但以指定的顺序生成数字。
# a random number generator
rng = lambda : np.random.randint(2,20)//2
# a non-random number generator
def nrng():
numbers = np.arange(1,10.5,0.5)
for i in range(len(numbers)):
yield numbers[i]
for j in range(10):
print('random number', rng())
print('non-random number', nrng())
Run Code Online (Sandbox Code Playgroud)
上面代码的问题是我无法nrng在最后一行调用,因为它是一个生成器。我知道重写上面代码的最直接方法是简单地循环非随机数而不是定义生成器。我更喜欢让上面的示例工作,因为我正在处理大量代码,其中包含一个接受随机数生成器作为参数的函数,并且我想添加传递非随机数字序列而不重写的功能整个代码。
编辑:我在评论中看到一些混乱。我知道 python 的随机数生成器生成伪随机数。这篇文章是关于用一个数字生成器替换伪随机数生成器,该数字生成器从非随机的、用户指定的1,1,2,2,1,0,1序列生成数字(例如,如果我想要的话,可以生成数字序列的生成器)。
我正在寻找一种方法来反转生成器对象.我知道如何反转序列:
foo = imap(seq.__getitem__, xrange(len(seq)-1, -1, -1))
Run Code Online (Sandbox Code Playgroud)
但是,作为输入的发生器和输出的反向发生器(len(seq)保持不变,可以使用原始序列中的值)可能类似吗?
我构建了这个有点神秘的python 3.3:
>>> [(yield from (i, i + 1, i)) for i in range(5)]
<generator object <listcomp> at 0x0000008666D96900>
>>> list(_)
[0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5, 4]
Run Code Online (Sandbox Code Playgroud)
如果我在列表构造函数中使用生成器理解,我会得到不同的结果:
>>> list((yield from (i, i + 1, i)) for i in range(5))
[0, 1, 0, None, 1, 2, 1, None, 2, 3, 2, None, 3, 4, 3, None, 4, 5, 4, None]
Run Code Online (Sandbox Code Playgroud)
为什么列表理解不返回列表?
我可以在python 2中得到类似的奇怪效果(使用集合理解,因为列表推导具有奇数范围):
>>> {(yield …Run Code Online (Sandbox Code Playgroud) 我是朱莉娅的新手.我主要在python中编程.
在python中,如果要迭代一大组值,通常会构造一个所谓的生成器来节省内存使用量.这是一个示例代码:
def generator(N):
for i in range(N):
yield i
Run Code Online (Sandbox Code Playgroud)
我想知道朱莉娅是否有类似的东西.阅读julia手册后,@ task macro似乎与python中的生成器具有相同(或类似)的功能.然而,经过一些实验,在julia中,内存使用量似乎比通常的数组大.
我@time在IJulia中使用来查看内存使用情况.这是我的示例代码:
[更新]:添加generator方法代码
(generator方法)
function generator(N::Int)
for i in 1:N
produce(i)
end
end
Run Code Online (Sandbox Code Playgroud)
(发电机版)
function fun_gener()
sum = 0
g = @task generator(100000)
for i in g
sum += i
end
sum
end
Run Code Online (Sandbox Code Playgroud)
@time fun_gener()
已用时间:0.420731828秒(已分配6507600字节)
(阵列版)
function fun_arry()
sum = 0
c = [1:100000]
for i in c
sum += i
end
sum
end
Run Code Online (Sandbox Code Playgroud)
@time fun_arry()
已用时间:0.000629629秒(已分配800144个字节)
谁能告诉我为什么@task在这种情况下需要更多空间?如果我想将内存使用量保存为处理大量值,我该怎么办?