我想构建一个高效的Python迭代器/生成器,它可以产生:
我称之为"composites_with_factors()"
假设我们已经有一个小于N的素数列表,或者一个可以做同样的素数生成器.
请注意我:
我想这可以通过一个聪明的递归发生器来完成......
因此,例如,对composites_with_factors(16)的调用可能会产生:
# yields values in form of "composite_value, (factor_tuple)"
2, (2)
4, (2, 2)
8, (2, 2, 2)
6, (2, 3)
12, (2, 2, 3)
10, (2, 5)
14, (2, 7)
3, (3)
9, (3, 3)
15, (3, 5)
5, (5)
7, (7)
11, (11)
13, (13)
Run Code Online (Sandbox Code Playgroud)
正如你从我的输出顺序中看到的那样,我设想通过从可用素数生成器上的最小素数开始,并输出小于N的素数的所有幂,然后再次尝试通过该素数的幂但是在每个阶段看看我是否可以申请额外素数(并且仍然小于N).当完成与THAT素数的所有组合时,将其丢弃,并使用素数生成器上可用的下一个最低素数重复.
我试图用"递归生成器"来做这件事让我很惊讶什么时候用"yield","提升StopIteration"或"return"来弹出递归,或者简单地脱离递归函数.
谢谢你的智慧!
附加说明:
我现在有一种方法可以做到这一点:我已经编写了一个函数来计算数字,所以我可以将它们分解为素数,并产生结果.没问题.我依靠"N号最低素数因子"的缓存来保持这种速度极快...... N高达1000万.
但是,一旦我退出缓存,我们就会变成"天真"的因素.(呸).
这篇文章的重点是:
我正在寻找一种在Python中执行此操作的简洁方法:
假设我有两个迭代器"iter1"和"iter2":也许是一个素数生成器和itertools.count().我先验地知道两者都是无限的并且单调递增.现在我想利用有两个参数的一些操作简单的"OP"(也许operator.add或operator.mul),并计算出每个元素的第一个迭代器与每一个元素的下一个,采用上述操作,则产生逐一时间,排序.显然,这本身就是一个无限的序列.(正如@RyanThompson在评论中所提到的:这将被称为这些序列的笛卡尔积 ...或者更准确地说,是该产品的第1类.)
什么是最好的方式:
允许的简化假设:
也允许:
我能想到这样做的唯一方法是一种"对角化"过程,在这种过程中,我保留了越来越多的部分处理的迭代,并且"向前看"所有可能的next()值的最小值,并产生.但是,即使在我开始对它进行编码之前,这种古怪的聚集和一堆deques似乎都是异乎寻常的.
请:那不是立足于事实,我的例子中提到的质数或计数()你的答案....我对这个非常的概念,不相关的素数和计算多种用途().
更新:天啊!多么棒的讨论!并通过非常彻底的解释得到一些很好的答案.非常感谢.StackOverflow摇滚; 你们好棒.
我将尽快深入研究每个答案,并给出示例代码.从我到目前为止所读到的内容来看,我最初的怀疑是确认没有"简单的Python成语"来做到这一点.相反,通过这种或那种方式,我无法避免无限期地保持iter1和iter2的所有产生的值.
FWIW:如果你想尝试你的解决方案,这是一个官方的"测试案例".
import operator
def powers_of_ten():
n = 0
while True:
yield 10**n
n += 1
def series_of_nines():
yield 1
n = 1
while True:
yield int("9"*n)
n += 1
op = operator.mul
iter1 = powers_of_ten()
iter2 = series_of_nines()
# given (iter1, iter2, op), create an iterator that yields:
# [1, …Run Code Online (Sandbox Code Playgroud) 这个操作有名字吗?而且:有一个封闭形式的表达吗?
我可以在Python中表达这一点,并且很容易进行计算:
from operator import mul
from itertools import combinations
from functools import reduce
def sum_of_product_of_subsets(list1, k):
val = 0
for subset in combinations(list1, k):
val += reduce(mul, subset)
return val
Run Code Online (Sandbox Code Playgroud)
我只是在寻找封闭的表单表达式,以便在设置大小变大时避免循环.
请注意,这与此问题不同:产品与所有组合的总和与每个组中的一个元素 - 该问题是关于笛卡尔积的乘积和.我正在寻找大小为k的组合集的乘积和; 我不认为他们是一样的.
要清楚,对于set(a,b,c,d),则:
k = 4 --> a*b*c*d
k = 3 --> b*c*d + a*c*d + a*b*d + a*b*c
k = 2 --> a*b + a*c + a*d + b*c + b*d + c*d
k = 1 --> a + b …Run Code Online (Sandbox Code Playgroud) 我正在使用AWS,Python和Boto库.
我想调用.start()或.stop()在Boto EC2实例上,然后"轮询"它直到它完成.
import boto.ec2
credentials = {
'aws_access_key_id': 'yadayada',
'aws_secret_access_key': 'rigamarole',
}
def toggle_instance_state():
conn = boto.ec2.connect_to_region("us-east-1", **credentials)
reservations = conn.get_all_reservations()
instance = reservations[0].instances[0]
state = instance.state
if state == 'stopped':
instance.start()
elif state == 'running':
instance.stop()
state = instance.state
while state not in ('running', 'stopped'):
sleep(5)
state = instance.state
print " state:", state
Run Code Online (Sandbox Code Playgroud)
但是,在最后一个while循环中,状态似乎"停滞"在"待定"或"停止"状态.强调"似乎",从我的AWS控制台,我可以看到实例确实使它"开始"或"停止".
我能解决这个问题的唯一方法是.get_all_reservations()在while循环中回忆起来,就像这样:
while state not in ('running', 'stopped'):
sleep(5)
# added this line: …Run Code Online (Sandbox Code Playgroud) 我想在Windows上使用Python 2.6来启动几个单独的命令窗口,每个窗口都运行自己的Python脚本.目的是:这些是客户端,我正在尝试使用来自多个准独立客户端的请求来加载服务器.
我不需要在运行期间或之后与客户端通信,但我确实需要发送每个不同的commmandline arg,并且我希望每个客户端的输出在其自己的"控制台"中滚动.
从DOS命令行,"start"命令执行我想要的操作.我可以:
start perf_test.py 2
Run Code Online (Sandbox Code Playgroud)
要么
start cmd /c perf_test.py 3
Run Code Online (Sandbox Code Playgroud)
要么
start cmd /c python perf_test.py 4
Run Code Online (Sandbox Code Playgroud)
(如果您为*.py文件正确设置了"文件关联",这些将对您有用.如果您需要帮助,还有其他线程.或者,使用python exe和/或脚本的完整路径.)
我的挑战是:如何从Python中获得相同的效果?
使用subprocess库,我尝试过这样的变体:
from subprocess import *
p = Popen(["perf_test.py", "4"], shell=True, stdin=PIPE)
Run Code Online (Sandbox Code Playgroud)
但即便如此shell=True,输出也会混合在我已经运行的窗口中.添加stdout=PIPE停止,但我必须阅读p.stdout或使用p.communicate().将"cmd"添加到Popen大致相同:
p = Popen(["cmd", "/c", "perf_test.py", "4"], shell=True, stdin=PIPE)
Run Code Online (Sandbox Code Playgroud)
以上都没有达到我正在寻找的效果,即:" 为这个脚本弹出一个新的,独特的窗口,并在自己的控制台中观看它的输出滚动 "(因为我真的想要运行这些客户端中的N个)在平行下).
我转向的另一件事几乎也有效.
import os
os.startfile("perf_test.py")
Run Code Online (Sandbox Code Playgroud)
这会立即返回,并弹出一个实际的dosbox.好极了!成功!也就是说,直到我尝试添加一个参数.这失败了:
os.startfile("perf_test.py 5")
Run Code Online (Sandbox Code Playgroud)
错误"系统找不到指定的文件"...因为它在文件名中添加了"[SPACE] 5".(参数的目的是每个"perf_test"需要有一个分配的ID,以便它们作为不同的实例命中服务器.)
我考虑过的其他方法,实际上并不喜欢各种原因:
Popen或启动.BAT文件 …我无法让 Python 的 jsonpickle 0.4.0 “递归”到包含自定义对象的自定义对象。这是显示我的问题的示例代码。
import jsonpickle
import jsonpickle.handlers
class Ball(object):
def __init__(self, color):
self.color = color
class Box(object):
def __init__(self, *args):
self.contents = args
class BallHandler(jsonpickle.handlers.BaseHandler):
def flatten(self, obj, data):
data['color'] = obj.color
return data
class BoxHandler(jsonpickle.handlers.BaseHandler):
def flatten(self, obj, data):
data['contents'] = obj.contents
return data
jsonpickle.handlers.registry.register(Ball, BallHandler)
jsonpickle.handlers.registry.register(Box, BoxHandler)
# works OK -- correctly prints: {"color": "white"}
white_ball = Ball('white')
print jsonpickle.encode(white_ball, unpicklable=False)
# works OK -- correctly prints: [{"color": "white"}, {"color": "green"}]
green_ball = Ball('green')
balls …Run Code Online (Sandbox Code Playgroud) python ×5
algorithm ×2
iterator ×2
amazon-ec2 ×1
boto ×1
console ×1
generator ×1
json ×1
jsonpickle ×1
popen ×1
subprocess ×1
windows ×1