我正在比较数字列表,并为匹配方向分配“分数”。每一次正面或负面的比赛都应该使参与者的得分增加1。
例如:
list1 =[5.6, -7.1, 6.4]
list2 =[4.5, -2.0, -4.2]应该给参与者打2分,因为5.6和4.5都是正(+1),-7.1和-2.0都是负(+1)。
我让它可以很好地比较积极的东西:
def score2(list1, list2):
count = 0
for index in range (0, len(list1)):
if list1[index] and list2[index] > 0:
count += 1
return count尽管-7.1和-2.0都是负的,但负片的部分仍然返回0。在前面的函数中,我将其作为elif部分,但我将其分离以进行调试:
def score3(list1, list2):
count = 0
for index in range (0, len(list1)):
if list1[index] and list2[index] < 0:
count += 1
return count有趣的是,如果我这么做了
print list1[1] and list2[1] < 0它可以打印True。所以我不确定score3到底出了什么问题。
发布于 2014-04-01 03:20:50
list1[index] and list2[index] < 0的意思是list1[index] and (list2[index] < 0)。and适用于list1[index]和list2[index] < 0的结果。要了解and和or的工作原理,请参阅the documentation。你想要的是:
list1[index] < 0 and list2[index] < 0在您的第一个示例测试中也发生了同样的情况,但是您没有注意到它,因为它恰好可以工作。对于这种情况,您同样应该这样做:
list1[index] > 0 and list2[index] > 0发布于 2014-04-01 03:29:03
你可以很容易地得到这个分数:
result = sum(x*y > 0 for x, y in zip(list1, list2))它怎麽工作?
zip()在元组中配对相应的元素:(5.6, 4.5), (-7.1, -2.0), (6.4, -4.2)
您可以使用生成器表达式遍历这些元组,并将两个数字相乘。如果两个数都是负数或两个数都是正数,则乘积将大于零。因此,如果两个数字具有相同的符号,则表达式x*y > 0的计算结果为True。
然后通过内置sum()对一系列True/False值求和,其中True计为1,False计为0。给你你想要的分数。
PS。这种解决方案比使用ifs更快。在现代硬件上,浮点乘法大约有4个周期,所有的计算都是线性的,没有任何条件跳跃,允许像流水线一样进行繁重的优化。
编辑
现在,你的score3()出了什么问题。
布尔运算符and / or的工作很慢,返回的第一个值使得表达式的结果是已知的。对于and,这是第一个计算结果为False的值(可以是空字符串、0、空列表、无等)。或者最后一个值,如果所有值都是“the”。
因此,在您的示例中,表达式的计算结果(针对索引1)如下:
-7.1 and -2.0 < 0-7.1为非零值,因此为True。表达式必须进一步求值。-2.0也是True,因此(-7.1 and -2.0)的计算结果为-2.0.现在,将该值与为True的0:-2.0 < 0进行比较。
我希望这能让你明白这一点。;)
发布于 2014-04-01 03:23:35
你可以使用zip和sum来理解列表:
sum([1 for l1,l2 in zip(list1,list2) if ((l1>=0 and l2 >=0) or (l1<0 and l2 < 0)) ])https://stackoverflow.com/questions/22770274
复制相似问题