在循环中比较列表中的值;Python
我在用Python 2.7。
我有两个不同的列表,A和B(为了让解释更清楚,我把它们简化了)。
A = [1, 2, 4, 3, 5]
B = [2, 0, 3, 2, 1]
我想比较这两个列表中每个位置的值,比如A[1]和B[1],然后统计A更大的次数(A“胜利”),两个值相同的次数(A“平局”),以及B更大的次数(A“失败”)。
为了让事情变得更复杂,我还在每次循环中使用random.shuffle()来随机改变列表的顺序。
我最开始尝试使用:
def listComp(listA, listB):
Awins = 0
Aties = 0
Alosses = 0
for i in range(0, whatever):
random.shuffle(listA)
random.shuffle(listB)
if A[0] > B[0]:
Awins += 1
elif A[0] == B[0]:
Aties += 1
elif A[0] < B[0}:
Alosses += 1
然后在每个if语句中,写额外的if语句来处理所有可能的情况。显然,随着列表的增大,这样做会变得非常繁琐。总得有更简单的方法吧?
5 个回答
2
我觉得你想用的是 zip
,另外我不太明白你为什么要在循环里面进行洗牌(不过我也不太清楚你想要达到什么效果)。我建议把洗牌放到循环外面,这样也能保持随机的效果。
def listComp(listA, listB):
wins = 0
ties = 0
losses = 0
shuffle(listA)
shuffle(listB)
for a, b in zip(listA, listB):
if a < b:
wins += 1
elif a == b:
ties += 1
else:
losses += 1
return wins, ties, losses
关于 zip
有一点要注意,它会根据你提供的最短列表来生成一个项目列表。举个例子:
zip([1, 2], ['a', 'b', 'c'])
会输出:
[(1, 'a'), (2, 'b')] # Note the missing 'c'
2
为了补充其他答案(并实现digivampire尝试的简化),你可以使用一个叫做cmp
的免费函数来简化比较的逻辑。这个函数会根据两个值的大小返回-1、0或1。然后我们可以count
每个值出现的次数。
for i in range(0, whatever):
random.shuffle(listA)
random.shuffle(listB)
results = [cmp(a, b) for a, b in zip(listA, listB)]
Awins += results.count(1)
Aties += results.count(0)
Alosses += results.count(-1)
进一步说,我们可以让Python为我们处理外层循环的逻辑和求和。这个想法是构建长度为3的列表,里面存放计数的结果(使用列表推导式遍历-1到1的范围),然后再用另一个列表推导式来获取这些结果whatever
次,最后用zip
把它们组合起来(这样就能得到三个列表,分别是胜利次数、平局次数和失败次数),然后对每个列表进行sum
操作。
def trial(listA, listB):
random.shuffle(listA)
random.shuffle(listB)
results = [cmp(a, b) for a, b in zip(listA, listB)]
return [results.count(i) for i in range(-1, 2)]
Awins, Aties, Alosses = (
sum(counts)
for counts in zip(*(
trial(listA, listB) for i in range(0, whatever)
))
)
4
听起来你想要用到 zip
这个功能:
def compare(A,B):
Awins = 0
Aties = 0
Alosses = 0
for i in range(0, whatever):
random.shuffle(listA)
random.shuffle(listB)
for a,b in zip(A,B):
if a > b:
Awins += 1
elif a == b:
Aties += 1
else:
Alosses += 1