【问题标题】:How to iterate with different values in for loop?如何在for循环中使用不同的值进行迭代?
【发布时间】:2019-09-18 11:49:16
【问题描述】:

我想知道我们是否可以通过硬编码在“for循环”中指定下一个要递增的值?

目前,我正在这样迭代: 例如:

for i in range(0, 10, 2):
    print(i)

输出将是0,2,4,6,8

如果我想要57 的值以及2 的增量,我该怎么做?

例如:

for i in range(0, 10, 2, 4, 5, 6, 7, 8):

【问题讨论】:

  • 你能提供一个你所拥有的输入和你想要的输出的例子吗?
  • 你可以做得很丑,有indexes = [2,4,5,6,7,8],然后是for i in indexes(或者完全跳过indexes,然后做for i in [2,4,5,6,7,8]
  • 谢谢!但是,如果我需要解析 1 到 1000 之间的增量例外,除了指定索引之外还有其他方法吗?
  • 那些例外是什么?
  • 例如:for i in range(1, 1000, 20);我需要介于 178、235、650 之间的值。我可以在 for 循环中这样做吗?

标签: python loops optimization iteration


【解决方案1】:

如果我正确理解您的问题,此代码适合您: 使用生成器理解:

pred = i%2 is 0
forced_values = [5, 7]

list((i for i in range(0, 10) if pred or i in forced_values))
# output: [0, 2, 4, 5, 6, 7, 8]

或等效:

sorted(list(range(0, 10, 2)) + forced_values)

执行时间比较:

基准测试:

n = 10000000 # size of range values
m = 10000000 # size of forced_value list

1。生成器理解的解决方案:

%%timeit
list((i for i in range(0, n) if i%2 is 0 or i in range(0, m)))
# 3.47 s ± 265 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

2。排序解决方案:

%%timeit
sorted(list(range(0, n, 2)) + list(range(0, m)))
# 1.59 s ± 11.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

或者使用无序列表,如果顺序不重要:

%%timeit
list(range(0, n, 2)) + list(range(0, m))
# 1.03 s ± 109 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

3。 @blhsing 提出的解决方案,带有more_itertools 包,特别是collate 函数:

%%timeit
l = []
for i in collate(range(0, n, 2), range(0, m)):
    l.append(i)
# 6.89 s ± 886 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

即使在非常大的列表中,最好的解决方案似乎也是第二个解决方案,它比其他建议的解决方案快 2 到 4 倍。

【讨论】:

  • 跳过列表部分并将其保留为生成器。 for i in (i for i in range(0,1000) if i%20 is 0 or i in [178, 235, 650]): print(i)
  • 完美!我很高兴我帮助了你。我稍微更改了代码以使其更清晰:-)
  • @micke 显然它可以保留生成器或将其变成列表。建议是仅在实际需要处理单个值时才将生成器转换为列表。在您之前的评论中,当您执行for i in (i for i in range (0,1000) if i% 20 is 0 or i in [178, 235, 650]): print (i) 时,您正在隐式地将生成器变成一个列表:-)
  • 就个人而言,我很失望你屈服于@blhsing。你可能已经被他相对较高的代表吓倒了。 sorted 函数假定的“低效率”对于如此小的列表大小肯定不应该是一个认真的考虑。可读性比效率上如此微小的提高重要得多。你觉得sorted 解决方案更清晰,我同意你的看法。
  • @JohnY collate(range(0, 10, 2), (5, 7))sorted(tuple(range(0, 10, 2)) + (5, 7)) 更不清晰?
【解决方案2】:

为了澄清,这里有一些相关的 cmets:

如果我需要解析 1 到 1000 之间的增量例外,除了指定索引之外还有其他方法吗?
例如:for i in range(1, 1000, 20);我需要介于 178、235、650 之间的值。我可以在 for 循环中这样做吗?

技术的答案是:是和否。 是的,因为您当然可以在 for 循环中执行此操作。 ,因为无法指定例外。 (否则它们就不会是例外,不是吗?)

您仍然使用for 循环,因为Python 的for 循环实际上与索引或范围无关。这是关于迭代任意对象。 碰巧,许多其他语言都有的简单数字for 循环最直接地被翻译成Python 作为一个范围内的循环。但实际上,Python for 循环的形式很简单

for x in y:
    # do stuff here

并且循环遍历y,无论y 是什么,只要它是可迭代的,x 在每次迭代中取y 的一个元素的值。就是这样。

但是,您似乎真正追求的是一种循环一堆大部分遵循简单模式的数字的方法。我可能会这样做:

values = list(range(1, 1000, 20)) + [178, 235, 650]
for i in sorted(values):
    print(i)

或者,如果您不介意更长的线路:

for i in sorted(list(range(1, 1000, 20)) + [178, 235, 650]):
    print(i)

【讨论】:

  • 谢谢!我很欣赏技术简报,帮助我更好地理解概念。
【解决方案3】:

你可以给for循环一个列表:

for i in [2, 4, 5, 6, 7, 8]:

如果它遵循算法,您还可以创建自定义迭代器。这在此处的另一个答案中有所描述:Build a Basic Python Iterator

【讨论】:

    猜你喜欢
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2010-09-11
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多