组合两个列表并打印对应于特定值的所有值

时间:2016-10-22 18:12:02

标签: python list python-3.x loops iteration

我需要组合两个列表,然后计算对应于某个值的所有值。

这两个清单是:

inControl = ["False", "False", "True", "True","False", "True", "False", "True", "True", "False", "False", "False", "False", "False", "False", "True", "False", "True", "False", "False"]

rts = [379, 396, 480, 443, 365, 280, 487, 446, 350, 367, 405, 391, 484, 359, 367, 305, 359, 479, 436, 333]

我需要对与所有rts值对应的所有False求和,然后对True值进行求和(它们全部按顺序排列)。

我基本上使用zip功能将两个列表组合在一起,但我完全不知道下一步该做什么......任何帮助都会受到赞赏。

非常感谢:)

4 个答案:

答案 0 :(得分:2)

看起来很奇怪布尔是字符串,但是......

使用zip,然后使用sum匹配元素。

(为Python 3中的其他部分重新创建zip因为zip是可迭代的)

inControl = ["False", "False", "True", "True","False", "True", "False", "True", "True", "False", "False", "False", "False", "False", "False", "True", "False", "True", "False", "False"]

rts = [379, 396, 480, 443, 365, 280, 487, 446, 350, 367, 405, 391, 484, 359, 367, 305, 359, 479, 436, 333]

z=zip(rts,inControl)
sf=sum(x[0] for x in z if x[1]=='False')
z=zip(rts,inControl)
st=sum(x[0] for x in z if x[1]=='True')
print(sf,st)

结果:

5128 2783

也许st可以通过与sum进行较少的字符串比较来计算:st=sum(rts)-sf(更多的附加内容,更少的字符串比较)

变种: True&的小循环假

s=dict()

for c in ['False','True']:
    z=zip(rts,inControl)
    s[c]=sum(x[0] for x in z if x[1]==c)

答案 1 :(得分:2)

Jean-François的解决方案可以很好地工作并且非常易读。但它确实对数据进行了两次传递。如果列表很小,这不是什么大问题,但如果它很大,你可以通过一次通过大致将操作时间减半。

一种通用的方法是:

totals = {}
for flag, value in zip(inControl, rts):
    totals[flag] = totals.setdefault(flag, 0) + value

此代码不假设inControl仅包含FalseTrue。它实际上可以有任意数量的唯一值。

一种可行的方法是使用Counter模块中的collections类。 Counter是用于跟踪计数的字典。添加两个计数器是显而易见的:相同键的值相加。我们可以为每对元素创建一个Counter实例,并将所有计数器相加。请注意,为每个元素创建Counter可能有点过分 - 上述解决方案更有效。但出于教育目的,此解决方案看起来像:

from collections import Counter
counters = (Counter({k: v}) for k, v in zip(inControl, rts))
sum(counters, Counter())

答案 2 :(得分:0)

您可以在列表理解或生成器exrpession的True位置或>>> [(e,0) if c=='False' else (0,e) for e, c in zip(rts, inControl)] [(379, 0), (396, 0), (0, 480), (0, 443), (365, 0), (0, 280), (487, 0), (0, 446), (0, 350), (367, 0), (405, 0), (391, 0), (484, 0), (359, 0), (367, 0), (0, 305), (359, 0), (0, 479), (436, 0), (333, 0)] 位置生成具有单个数字的元组:

reduce

然后,您可以使用>>> reduce(lambda x, y: (x[0]+y[0], x[1]+y[1]), (((e,0) if c=='False' else (0,e) for e, c in zip(rts, inControl)))) (5128, 2783)

对一系列元组求和
False

您实际上可以使用True>>> t=reduce(lambda x, y: (x[0]+y[0], x[1]+y[1]), ((e if c=='False' else 0, e if c=='True' else 0) for e, c in zip(rts, inControl))) >>> t[False] 5128 >>> t[True] 2783 布尔值来访问元组:

map

或者,如果对您更有意义,可以使用>>> map(sum, zip(*((e,0) if c=='False' else (0,e) for e, c in zip(rts, inControl)))) [5128, 2783]

>>> dict(zip([False, True], map(sum, zip(*[(e,0) if c=='False' else (0,e) for e, c in zip(rts, inControl)]))))
{False: 5128, True: 2783}

或者,你可以创建一个带有和的字典:

.groupby()

如果你有熊猫,一个很好的方法就是使用sum>>> import pandas as pd >>> df=pd.DataFrame({'rts':rts, 'inControl':inControl}) >>> df inControl rts 0 False 379 1 False 396 2 True 480 3 True 443 4 False 365 5 True 280 6 False 487 7 True 446 8 True 350 9 False 367 10 False 405 11 False 391 12 False 484 13 False 359 14 False 367 15 True 305 16 False 359 17 True 479 18 False 436 19 False 333 >>> df.groupby(inControl).sum() rts False 5128 True 2783

styles.xml

答案 3 :(得分:0)

假设:

inControl = ["False", "False", "True", "True","False", "True", "False", "True", "True", "False", "False", "False", "False", "False", "False", "True", "False", "True", "False", "False"]
rts = [379, 396, 480, 443, 365, 280, 487, 446, 350, 367, 405, 391, 484, 359, 367, 305, 359, 479, 436, 333]

我假设inControl是一个字符串列表,而不是一个布尔列表。为了我的解决方案,我将inControl转换为布尔值列表:

inControl = [element == 'True' for element in inControl]  # ==> [False, False, ...]

使用itertools.compress计算所有True元素的总和:

import itertools
true_sum = sum(itertools.compress(rts, inControl))  # 2783

现在,我们可以计算false_sum

grand_sum = sum(rts)              # 7911
false_sum = grand_sum - true_sum  # 5128