以下代码可用(demo)
f=lambda m, x:m and(x&1 and m.pop(0)or m.pop(0)[::-1])+f(m, x+1)
print(f([[4, 3, 2, 1], [5, 6, 7, 8], [12, 11, 10, 9], [13, 14, 15, 16]],0))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
这里有逻辑:
m.pop(0) if x&1 else m.pop(0)[::-1]
请解释为什么折叠到以下视图时代码无法正确执行?
[m.pop(0)[::-1],m.pop(0)][x&1]
我对Python不太了解,非常感谢您的帮助。
UPD:如果更改逻辑,则会得到以下结果:
f=lambda m,x:m and([m.pop(0)[::-1],m.pop(0)][x&1])+f(m,x+1)
print(f([[4, 3, 2, 1], [5, 6, 7, 8], [12, 11, 10, 9], [13, 14, 15, 16]],0))
# [1, 2, 3, 4, 13, 14, 15, 16]
PS。高尔夫球代码(如果这很重要,则代码的本质是它以蛇的形式绕过二维数组)
解决方案:
[m.pop(0)[::-1],m.pop(0)][x&1]
=> (lambda: m.pop(0)[::-1], lambda: m.pop(0))[x&1]()
。
答案 0 :(得分:2)
问题在于三元组if
仅评估其分支之一,因此仅发生一个pop
调用。在您的代码中,有两个pop
调用都被评估。
[m.pop(0)[::-1], m.pop(0)][x&1]
为避免这种情况,如果必须以这种方式编写并且不使用三元组A if C else B
,则必须对每种情况进行重击,lambda:
,然后在对情况列表进行索引后,调用选择的情况:
[lambda: m.pop(0)[::-1], lambda: m.pop(0)][x&1]()
然后可以删除通用表达式:
item = m.pop(0)
[lambda: item[::-1], lambda: item][x&1]()
在进行重击之前执行此操作会导致:
item = m.pop(0)
[item[::-1], item][x&1]
如果项是可切片的,则不会产生错误。但这将无用地产生和丢弃项目的反向副本。但是,如果在x为奇数的情况下说int
,而在偶数时说list
则会导致错误:
>>> 3[::-1]
TypeError: 'int' object has no attribute '__getitem__'
因为表达式中的所有子表达式都将被求值,除非它们已被lambda延迟。
thunk是不带参数的函数的术语。
答案 1 :(得分:1)
给定表达式的所有三个版本之间的短路行为都不同(如果Query<Object1> q1 = currentSession.createQuery("from Object1 o where o.objectNumber= :objectNumber");
q1.setParameter("objectNumber", objectNumber);
Object1 obj1 = q1.getSingleResult();
Query<Long> q2 = currentSession.createQuery("select count(id) from Object2 o where :object1param in elements(o.associatedObjects));
q2.setParameter("object1param ", obj1);
的某些元素为false)。 m
惯用语通常在Python具有条件运算符之前使用,但是如果a and b or c
为false则不适用。