【问题标题】:Python best practice for iterating until x successes?迭代直到 x 成功的 Python 最佳实践?
【发布时间】:2014-02-11 18:21:15
【问题描述】:

如果这在其他地方得到了回答,我深表歉意,但如果是这样,我还没有找到。

我想遍历一个对象并构建一个满足我评估标准的 x 个项目的列表。一旦达到我的阈值项目数,我想停止迭代。我曾尝试使用 while 循环和计数器来执行此操作,这在 Python 中几乎从未见过,而我现在正在使用 for 循环和一开始的测试条件来执行此操作。我现在所做的工作有效,但我认为必须有更好的模式,也许可以使用我运行 x 次的生成器。

list_length = 25
list_results = []

for item in some_object:

    # test if list length condition met
    results_count = len(list_results)
    if results_count >= list_length:
        break

    # length condition not met, process some more
    if item == some_criteria:
        list_results.append(item)

我几乎找不到这样的例子这一事实通常很好地表明我做错了 - 任何对最佳实践的见解将不胜感激 - 谢谢!

【问题讨论】:

    标签: python while-loop iteration


    【解决方案1】:

    IIUC,itertools.islice呢?

    >>> from itertools import islice
    >>> some_object = range(1000)
    >>> good_values = (x for x in some_object if x % 5 == 0)
    >>> keep = list(islice(good_values, 0, 25))
    >>> len(keep)
    25
    

    即使没有 25 个也可以使用:

    >>> good_values = (x for x in some_object if x > 10**6)
    >>> keep = list(islice(good_values, 0, 25))
    >>> len(keep)
    0
    

    【讨论】:

    • 为什么你认为islice 是一个更好的解决方案,而不是普通的切片[:25](在这个特殊的情况下是c)?
    • @PaoloCasciello:如果some_object 很长,并且测试标准很慢怎么办?找到前 25 个之后,没有理由继续工作。some_object 甚至可能一开始就无法实现:例如,它可能是 itertools.count()
    • @PaoloCasciello:islice 与生成器一起使用,这个答案使用。你不能在生成器上使用[:25]
    • @user2357112 呃……对……我完全忘记了我不能在 gen 上使用 slice ……抱歉 -_-'
    • @AlanS:括号表示它是一个生成器表达式(参见教程中的here),因此不会立即计算。在控制台中,键入 g = (x for x in range(100) if x % 5 == 0),然后键入 print(g)。然后输入几次next(g),然后输入list(g)
    【解决方案2】:

    添加第 25 项后,您可以中断:

    for item in some_object:
        if item == some_criteria:
            list_results.append(item)
            if len(list_results) >= 25:
                break
    

    对我来说,任何更复杂的优化似乎都为时过早,除非有充分的理由让它变得更复杂。

    【讨论】:

    • 几个很棒的解决方案 - 谢谢!在我的例子中,我通过一个非常缓慢的第 3 方 API 提取数据,所以我想迭代尽可能少的周期(我不想迭代 1,000 或 100 万次以仅分割 25 次成功)。跨度>
    • @AlanS:请注意,islice 的答案也会在 25 次成功后停止。不过,您需要使用生成器。
    • @user2357112 谢谢 - 正如其他 cmets 中提到的,我将对此进行更多探索。很有帮助。
    【解决方案3】:

    重用你的变量名:

    import itertools
    itertools.islice( ( item for item in some_object if item == some_criteria ), list_length )
    

    【讨论】:

      猜你喜欢
      • 2012-02-19
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      • 2012-09-10
      • 2012-05-21
      相关资源
      最近更新 更多