我正在为C#/ .NET寻找一个合适的词法扫描程序生成器 - 支持Unicode字符类别,并生成一些可读和有效的代码.谁知道一个?
编辑:我需要支持Unicode类别,而不仅仅是Unicode字符.目前仅有Lu(字母,大写)类别中有1421个字符,我需要非常具体地匹配许多不同的类别,而不是手写它所需的字符集.
此外,实际代码是必须的 - 这排除了生成二进制文件然后与驱动程序一起使用的东西(即GOLD)
编辑:ANTLR尚不支持Unicode类别.但是,它存在一个悬而未决的问题,所以它有朝一日可能符合我的需求.
test = ["a","b","c","d","e"]
def xuniqueCombinations(items, n):
if n==0: yield []
else:
for i in xrange(len(items)-n+1):
for cc in xuniqueCombinations(items[i+1:],n-1):
yield [items[i]]+cc
x = xuniqueCombinations(test, 3)
print x
Run Code Online (Sandbox Code Playgroud)
输出
"generator object xuniqueCombinations at 0x020EBFA8"
Run Code Online (Sandbox Code Playgroud)
我希望看到它找到的所有组合.我怎样才能做到这一点?
怎么了?有人可以解释一下这里发生了什么,我在紧密循环中改变了:
## j=i
## while j < ls - 1 and len(wordlist[j]) > lc: j+=1
j = next(j for j in range(i,ls) if len(wordlist[j]) <= lc)
Run Code Online (Sandbox Code Playgroud)
评论的版本运行整个程序:625毫秒,下一个生成器版本在2.125秒的时间内运行整个程序.
有什么理由可以说这个更加pythonic的版本会导致性能上的这种灾难?
编辑:也许它是由使用psyco模块引起的?当然至少没有psyco的Python 2.7的运行时间对于下一个版本来说是2.141,意味着与使用psyco的Python 2.6几乎相同.
删除*.pyc文件后,我得到的代码没有减速.然后,当我从库模块中删除了psyco的导入时,我还得到了2.6时序,没有psyco使用,非psyco版本和psyco版本的结果(现在库例程也慢了,它的时间也相关:)
不是psyco:
Psyco是:
在带有2GB RAM的WindowsXP AMD Sempron 3100+系统中运行.使用两个全局变量计算循环和调用:
j=i
callcount += 1
while j < ls - 1 and len(wordlist[j]) > lc:
j+=1
loopcount += 1
Run Code Online (Sandbox Code Playgroud)
使用psyco进行测试输入的结果:
Finished in 625 ms
Loopcount: 78317 …Run Code Online (Sandbox Code Playgroud) python生成器是列表的良好替代品,在大多数情况下,我希望检查空条件,这是普通生成器无法实现的.我正在尝试编写一个包装器,它将允许检查空状态,但仍然是懒惰的并且提供了生成器的好处.
class mygen:
def __init__(self,iterable):
self.iterable = (x for x in iterable)
self.peeked = False
self.peek = None
def __iter__(self):
if self.peeked:
yield self.peek
self.peeked = False
for val in self.iterable:
if self.peeked:
yield self.peek
self.peeked = False
yield val
if self.peeked:
yield self.peek
self.peeked = False
def __nonzero__(self):
if self.peeked:
return True
try:
self.peek = self.iterable.next()
self.peeked = True
return True
except:
return False
Run Code Online (Sandbox Code Playgroud)
样品用法:
def get_odd(l):
return mygen(x for x in l if x%2)
def print_odd(odd_nums): …Run Code Online (Sandbox Code Playgroud) 我有一个非常大的PHP(5.6)数组,动态生成,我想转换为JSON.问题是数组太大而不适合内存 - 当我尝试处理它(耗尽的内存)时会出现致命的错误.所以我发现,使用发生器,内存问题将消失.
这是我到目前为止尝试过的代码(这个简化示例显然不会产生内存错误):
<?php
function arrayGenerator()// new way using generators
{
for ($i = 0; $i < 100; $i++) {
yield $i;
}
}
function getArray()// old way, generating and returning the full array
{
$array = [];
for ($i = 0; $i < 100; $i++) {
$array[] = $i;
}
return $array;
}
$object = [
'id' => 'foo',
'type' => 'blah',
'data' => getArray(),
'gen' => arrayGenerator(),
];
echo json_encode($object);
Run Code Online (Sandbox Code Playgroud)
但PHP似乎没有对生成器中的值进行JSON编码.这是我从previuos脚本得到的输出:
{
"id": "foo",
"type": "blah",
"data": …Run Code Online (Sandbox Code Playgroud) 我想我知道变量和生成器在Python中是如何工作的.
但是,以下代码让我感到困惑.
from __future__ import print_function
class A(object):
x = 4
gen = (x for _ in range(3))
a = A()
print(list(a.gen))
Run Code Online (Sandbox Code Playgroud)
运行代码(Python 2)时,它说:
Run Code Online (Sandbox Code Playgroud)Traceback (most recent call last): File "Untitled 8.py", line 10, in <module> print(list(a.gen)) File "Untitled 8.py", line 6, in <genexpr> gen = (x for _ in range(3)) NameError: global name 'x' is not defined
在Python 3中,它说,NameError: name 'x' is not defined
但是,当我运行时:
from __future__ import print_function
class A(object):
x = 4
lst = [x for …Run Code Online (Sandbox Code Playgroud) 以下内容摘自David Beazley关于发电机的幻灯片(这里有感兴趣的人).
Task定义了一个类,它包含一个生成期货的生成器,Task类,完整(没有错误处理),如下:
class Task:
def __init__(self, gen):
self._gen = gen
def step(self, value=None):
try:
fut = self._gen.send(value)
fut.add_done_callback(self._wakeup)
except StopIteration as exc:
pass
def _wakeup(self, fut):
result = fut.result()
self.step(result)
Run Code Online (Sandbox Code Playgroud)
在一个示例中,还定义了以下递归函数:
from concurrent.futures import ThreadPoolExecutor
import time
pool = ThreadPoolExecutor(max_workers=8)
def recursive(n):
yield pool.submit(time.sleep, 0.001)
print("Tick :", n)
Task(recursive(n+1)).step()
Run Code Online (Sandbox Code Playgroud)
以下两个案例:
从Python REPL中,如果我们定义它们(或者如果我们将它们放在一个文件中则导入它们),然后使用以下命令跳转启动递归:
Task(recursive(0)).step()
Run Code Online (Sandbox Code Playgroud)
它开始打印,似乎已超过递归限制.它显然不会超过它,打印堆栈级别表明它在整个执行过程中保持不变.还有其他事情我不太明白.
注意:如果你这样执行它,你需要杀死python进程.
如果我们将所有内容(Task,recursive)放在一个文件中:
if __name__ == "__main__":
Task(recursive(0)).step()
Run Code Online (Sandbox Code Playgroud)
然后运行它python myfile.py,它停止滴答7( …
steps_per_epoch在理想情况下调用函数fit_generator()时需要设置值是number of total samples/ batch size什么?
我正在尝试创建一个生成器,它返回给定范围内的数字,该数字通过函数给出的特定测试foo.但是我希望这些数字以随机顺序进行测试.以下代码将实现此目的:
from random import shuffle
def MyGenerator(foo, num):
order = list(range(num))
shuffle(order)
for i in order:
if foo(i):
yield i
Run Code Online (Sandbox Code Playgroud)
问题
该解决方案的问题在于,有时范围将非常大(num可能是有序的10**8和向上的).在内存中有这么大的列表时,这个功能会变慢.我试图通过以下代码避免此问题:
from random import randint
def MyGenerator(foo, num):
tried = set()
while len(tried) <= num - 1:
i = randint(0, num-1)
if i in tried:
continue
tried.add(i)
if foo(i):
yield i
Run Code Online (Sandbox Code Playgroud)
这在大多数情况下运行良好,因为在大多数情况下num会非常大,foo会传递合理数量的数字,并且__next__调用该方法的总次数会相对较少(例如,最多200次通常要小得多) .因此,我们可能会偶然发现通过foo测试的值,并且tried永远不会变大.(即使它只通过10%的时间,我们也不会期望tried大致超过2000左右.)
但是,当它num很小时(接近__next__调用该方法的次数,或者foo大部分时间都失败),上述解决方案变得非常低效 - …
如果您在Python 3.7中有一个列表:
>>> li
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)
您可以n使用两种常见的Python习语之一将其转换为每个长度的块列表:
>>> n=3
>>> list(zip(*[iter(li)]*n))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
Run Code Online (Sandbox Code Playgroud)
因为(9,10)不是长度,所以丢弃最后一个不完整的元组n
你也可以这样做:
>>> [li[i:i+n] for i in range(0,len(li),n)]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
Run Code Online (Sandbox Code Playgroud)
如果你想要最后一个子列表,即使它有少于n元素.
假设我现在有一个发电机,gen未知长度或终端(所以呼叫list(gen))或sum(1 for _ in gen)不明智)我想要每个块.
我能够想出的最好的生成器表达式是这样的:
from itertools import zip_longest
sentinel=object() # for use in filtering out ending …Run Code Online (Sandbox Code Playgroud) generator ×10
python ×7
performance ×2
python-3.x ×2
.net ×1
c# ×1
coroutine ×1
json ×1
keras ×1
optimization ×1
parsing ×1
php ×1
recursion ×1
shuffle ×1
variables ×1
while-loop ×1
yield ×1