在列表推导式中重复调用一个方法

3

考虑一个名为'my_list'的列表,其内容如下:

['10', '100', '1,000', '10,000', 100,000']

我想验证my_list是一个字符串化的整数列表,这些整数是10的倍数,并按升序排序,因此我做了以下操作:

int_list = [int(each_int.replace(',', '')) for each_int in my_list]

boolean = all([int_list[idx] == int_list[idx-1]*10 for idx in xrange(1, len(int_list))])

我的问题是len()会在每次迭代时被调用吗?在这种情况下,哪种方法更好?

  1. 将长度分配给一个变量,并在列表推导式中使用该变量而不是len()本身
  2. 没有关系,len()仅在所有迭代中执行一次

如果是2.,那么它适用于例如,当我遍历字典列表的值/键(或仅是字典)的情况吗?

例如:d_list = [set(value) for value in my_dict.values()]


1
len 仅在传递到 xrange 时调用一次,之后推导式将迭代 xrange 的结果。同样,使用 my_dict.values() 时调用也仅发生一次。这与 for 循环的情况类似:循环构造函数仅发生一次。 - Matthew Trevor
1个回答

1
你可以这样做:

my_list = ['10', '100', '1,000', '10,000', '100,000']

int_list = [int(each_int.replace(',', '')) for each_int in my_list]

>>> print all(i*10==j for i,j in zip(int_list, int_list[1:]))
True

这将避免不必要的计算重复,并且比较方式为除法,因此速度更快。我还用 all(...) 替换了 all([...]),因为 all 可以处理生成器并且可以避免创建临时列表。

1
请注意,在Python 2中(提问者似乎在使用),您的除法检查将无法正常工作,因为对于100到109之间的任何整数jj / 10 == 10都将是True。当然,您可以通过使用float调用或使用from __future__ import division来解决这个问题,但保留问题中的乘法检查似乎更简单。不过,您的zip迭代方式更好! - Blckknght

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接