当前位置: 首页 > 面试题库 >

使用itertools.product并想要播种值

糜帅
2023-03-14
问题内容

因此,我编写了一个小脚本来从网站下载图片。它通过7个字母字符值,其中第一个字符始终是数字。问题是,如果我想停止脚本并再次启动它,则必须重新开始。

我可以用我获得的最后一个值以某种方式播种itertools.product,这样我就不必再遍历它们。

感谢您的任何投入。

这是代码的一部分:

numbers = '0123456789'
alnum = numbers + 'abcdefghijklmnopqrstuvwxyz'

len7 = itertools.product(numbers, alnum, alnum, alnum, alnum, alnum, alnum) # length 7

for p in itertools.chain(len7):
    currentid = ''.join(p)

    #semi static vars
    url = 'http://mysite.com/images/'
    url += currentid

    #Need to get the real url cause the redirect
    print "Trying " + url
    req = urllib2.Request(url)
    res = openaurl(req)
    if res == "continue": continue
    finalurl = res.geturl()

    #ok we have the full url now time to if it is real
    try: file = urllib2.urlopen(finalurl)
    except urllib2.HTTPError, e:
        print e.code

    im = cStringIO.StringIO(file.read())
    img = Image.open(im)
    writeimage(img)

问题答案:

这是一个基于pypy库代码的解决方案(感谢agf在评论中的建议)。

状态可以通过.state属性获得,也可以通过.goto(state)位置state序列的索引(从0开始)进行重置。最后有一个演示(恐怕您需要向下滚动)。

这比丢弃值要快得多。

> cat prod.py

class product(object):

    def __init__(self, *args, **kw):
        if len(kw) > 1:
            raise TypeError("product() takes at most 1 argument (%d given)" %
                             len(kw))
        self.repeat = kw.get('repeat', 1)
        self.gears = [x for x in args] * self.repeat
        self.num_gears = len(self.gears)
        self.reset()

    def reset(self):
        # initialization of indicies to loop over
        self.indicies = [(0, len(self.gears[x]))
                         for x in range(0, self.num_gears)]
        self.cont = True
        self.state = 0

    def goto(self, n):
        self.reset()
        self.state = n
        x = self.num_gears
        while n > 0 and x > 0:
            x -= 1
            n, m = divmod(n, len(self.gears[x]))
            self.indicies[x] = (m, self.indicies[x][1])
        if n > 0:
            self.reset()
            raise ValueError("state exceeded")

    def roll_gears(self):
        # Starting from the end of the gear indicies work to the front
        # incrementing the gear until the limit is reached. When the limit
        # is reached carry operation to the next gear
        self.state += 1
        should_carry = True
        for n in range(0, self.num_gears):
            nth_gear = self.num_gears - n - 1
            if should_carry:
                count, lim = self.indicies[nth_gear]
                count += 1
                if count == lim and nth_gear == 0:
                    self.cont = False
                if count == lim:
                    should_carry = True
                    count = 0
                else:
                    should_carry = False
                self.indicies[nth_gear] = (count, lim)
            else:
                break

    def __iter__(self):
        return self

    def next(self):
        if not self.cont:
            raise StopIteration
        l = []
        for x in range(0, self.num_gears):
            index, limit = self.indicies[x]
            l.append(self.gears[x][index])
        self.roll_gears()
        return tuple(l)

p = product('abc', '12')
print list(p)
p.reset()
print list(p)
p.goto(2)
print list(p)
p.goto(4)
print list(p)
> python prod.py 
[('a', '1'), ('a', '2'), ('b', '1'), ('b', '2'), ('c', '1'), ('c', '2')]
[('a', '1'), ('a', '2'), ('b', '1'), ('b', '2'), ('c', '1'), ('c', '2')]
[('b', '1'), ('b', '2'), ('c', '1'), ('c', '2')]
[('c', '1'), ('c', '2')]

您应该对其进行更多测试-我可能犯了一个愚蠢的错误-但是这个想法很简单,因此您应该可以解决它:o)您可以自由使用我的更改;不知道原始的pypy许可证是什么。

也不state是真正的完整状态-它不包括原始参数-只是序列的索引。也许最好把它称为索引,但是代码中已经有索引了。

更新

这是一个简单的版本,具有相同的想法,但是可以通过转换数字序列来工作。因此,您只需将imapcount(n)偏移量即可n

> cat prod2.py

from itertools import count, imap

def make_product(*values):
    def fold((n, l), v):
        (n, m) = divmod(n, len(v))
        return (n, l + [v[m]])
    def product(n):
        (n, l) = reduce(fold, values, (n, []))
        if n > 0: raise StopIteration
        return tuple(l)
    return product

print list(imap(make_product(['a','b','c'], [1,2,3]), count()))
print list(imap(make_product(['a','b','c'], [1,2,3]), count(3)))

def product_from(n, *values):
    return imap(make_product(*values), count(n))

print list(product_from(4, ['a','b','c'], [1,2,3]))

> python prod2.py 
[('a', 1), ('b', 1), ('c', 1), ('a', 2), ('b', 2), ('c', 2), ('a', 3), ('b', 3), ('c', 3)]
[('a', 2), ('b', 2), ('c', 2), ('a', 3), ('b', 3), ('c', 3)]
[('b', 2), ('c', 2), ('a', 3), ('b', 3), ('c', 3)]

(这里的缺点是,如果您要停止并重新启动,则需要跟踪自己已使用了多少个)



 类似资料:
  • 本文向大家介绍Laravel 使用MySQL Dump播种,包括了Laravel 使用MySQL Dump播种的使用技巧和注意事项,需要的朋友参考一下 示例 遵循前面创建种子的示例。本示例使用MySQL Dump在项目数据库中播种表。必须在播种之前创建表。 $sql将成为users.sql转储的内容。转储应具有INSERT INTO语句。存储转储的位置将取决于您。在上面的示例中,它存储在项目目录中

  • 问题内容: 我对Java和Maven还是比较陌生的,但是我无法想象如果不使用Maven就开始一个新的Java项目。 我想提供一种人类可读的项目模型的想法在许多语言中都是普遍希望的。当您的应用程序依赖大量外部库时,尤其如此。 是否有其他任何项目管理或针对Java以外的语言的构建工具,这些语言本质上与Maven相似;也就是说,是否为项目维护者提供了一种机制来指定依赖关系和构建顺序? 问题答案: 这是我

  • 我在这里读了这个答案,也在这里读了这个答案,我正在努力找出最适合我的情况。 我在中启动一个服务,在这里我发出一个HTTP请求,并得到一个作为响应。然后我广播这个,并在我的活动中接收它。 问题是,用户显然可以通过打开抽屉并选择一个选项导航到另一个活动,而我可能会错过广播。 很明显,我可以让我的所有活动扩展一个抽象类,这个抽象类扩展了这里提到的,但我不能100%肯定这是最好的解决方案。如果用户在我收到

  • 问题内容: 我知道要遍历关键字几个维度的列表。例如,如果我有这个: 我用它,我有这样的事情: 是否有一种等效的,简单的方法可以对数组执行相同的操作? 问题答案: 这个问题已经被问过几次了: 使用numpy构建两个数组的所有组合的数组 第一个链接具有一个有效的numpy解决方案,尽管没有提供基准测试,但据称它比itertools快几倍。该代码由名为pv的用户编写。如果您认为有用,请点击链接并支持他的

  • 我需要从类B中的方法C返回一个值。 我希望我的代码像这样处理:1 - 2 - 3 - 4 - 5 但它的处理方式是:1-4-5-2-3 (如您所见,我在代码中添加了一些日志。) 我已经处理这个问题一个多星期了,但我找不到问题。 我在这个问题中删除了一些无用的代码。 问题是什么?我如何解决这个问题? 我重写了这篇文章,因为有人说我把代码缩短得太多了。 希望足够了! 提前谢谢你!

  • 问题内容: 我正在尝试分发在几个链接的容器中运行的一组连接的应用程序,这些容器包括一个mongo数据库,该数据库需要: 分发包含一些种子数据; 允许用户添加其他数据。 理想情况下,数据还将保存在链接的数据卷容器中。 我可以使用不装载任何卷的基本实例(dockerhub映像:-本质上是不带该语句的基本mongo Dockerfile )和配置的方式将数据放入容器中: 其中与Dockerfile 位于