Python 用if语句增加理解变量?
我试图学习Python的理解,但我被卡住了。当条件为Python 用if语句增加理解变量?,python,python-3.x,list,list-comprehension,Python,Python 3.x,List,List Comprehension,我试图学习Python的理解,但我被卡住了。当条件为True时,我试图增加我的count变量,并在循环后返回该计数。这是我的密码: list = [1,2,4,5,7,8,10] d = 3 count = 0 return [count for x in range(len(list)) if list[x] + d in list and list[x] + 2 * d in list] 每次我的条件为True时,它都返回“0”。当我尝试在理解中添加count+=1时,它给
True
时,我试图增加我的count
变量,并在循环后返回该计数。这是我的密码:
list = [1,2,4,5,7,8,10]
d = 3
count = 0
return [count for x in range(len(list))
if list[x] + d in list and list[x] + 2 * d in list]
每次我的条件为True时,它都返回“0”
。当我尝试在理解中添加count+=1
时,它给了我一个SyntaxError
你非常接近。列表理解不能以您希望的方式存储和重用变量;它们只能包含表达式。一种解决方案是将sum
与生成器表达式一起使用
此解决方案的好处是避免了构建列表的开销,而这对于计算满足条件的元素数是不必要的
A = [1,2,4,5,7,8,10]
A_set = set(A)
d = 3
count = 0
res = sum(1 for x in range(len(A)) if \
(A[x]+d in A_set) and (A[x]+2*d in A_set))
# 3
注意,永远不要在类之后命名变量。此外,您可以使用set
进行O(1)查找
还请注意,我们在列表理解之外构造A_集
,否则将为范围(len(A))
的每次迭代计算它。如果您只需要发生的次数,请返回列表的长度:
len([count for x in range(len(list))
if list[x]+d in list and list[x]+2*d in list])
记住,这是一个列表理解;您不能添加任意操作,例如分配。不要以这种方式工作。从概念上讲,它们允许您设置和过滤列表中的单个元素,而不是累积到单个变量中
不过,有一个标准的习语可以用来绕开这个问题。基本上,你可以根据你的条件生成一个布尔数,或者只保留你想要的所有元素的布尔数,然后丢弃其他的布尔数
作为进一步的改进,我建议使用理解而不是列表。它看起来几乎相同,但支持延迟求值。这意味着您可以获得一行程序的所有好处,而不必将标志值列表存储在内存中
以下是第一个选项的外观:
L = [1,2,4,5,7,8,10]
count = sum((x + d in L and x + 2 * d in L) for x in L)
第二个选项如下所示:
L = [1,2,4,5,7,8,10]
count = sum(1 for x in L if (x + d in L and x + 2 * d in L))
请注意,我将变量list
重命名为L
,这样它就不会影响内置函数。是否
for x in lst:
if x+d in lst and x+2*d in lst:
count += 1
或使用len:
count = len([_ for x in lst if x+d in lst and x+2*d in lst])
或使用总和:
count = sum(1 for x in lst if x+d in lst and x+2*d in lst)
或使用集合(准备好惊讶):
以下是1000个连续数字列表中的性能数字:
loop: 20.3 ms ± 8 ms
len: 25.4 ms ± 8.22 ms
sum: 18.3 ms ± 5.06 ms
sets: 272 µs ± 19 µs (~100x faster)
这不是性能的保证。在这种情况下,集合可能也是内存效率最低的解决方案。但它确实有效(看起来相当不错)
另外,不要命名一个变量list
,它是Python中的内置函数,覆盖它会导致各种混乱。要清楚,您正在尝试编写一个单行程序来计算列表中e+3
和e+6
的元素数?@madphypersister-Yep这是rightList理解只能包含表达式count=count+1
是一个赋值(语句),因此您不能在那里使用它。@Matiascero感谢您澄清这一点!使用设置
的触感很好+1但无需在该范围内迭代。直接迭代A
。在理解范围之外计算A_集
是非常重要的-内联集(A)
将抵消任何好处,因为重复重建集的成本。感谢回复!我将比较所有这些解决方案。谢谢你的第二个列表技巧。谢谢你的解释和示例代码!这真的帮了我忙,谢谢你的回复!虽然涵盖了其他答案中的大部分内容,但时间点很好+1它引发了一个错误:NameError:名称“\u1”不是defined@sword1st刚刚检查过需要python 3,对于python 2,它抛出NameError
count = len(({x + d for x in lst} | {x + 2 * d for x in lst}) & set(lst))
loop: 20.3 ms ± 8 ms
len: 25.4 ms ± 8.22 ms
sum: 18.3 ms ± 5.06 ms
sets: 272 µs ± 19 µs (~100x faster)