在python中反转循环?

时间:2017-04-17 14:43:30

标签: python list for-loop

我不确定我的标题是否正是我想要做的,但实质上我得到了列表列表的平均值,我希望它不是在列表中添加而是在它们之间添加:

listoflists = [[1,2,3], [1,0,4], [0,5,1]]
#want [1, 3.5, 2.67]
final = []
for i in range(len(listoflists)):
    count = 0
    val = 0
    for j in range(len(listoflists[i])):
        if listoflists[i][j] != 0:
            count += 1
            val += listoflists[i][j]
    final.append(float(val)/count)
print final #currently returns [2.0, 2.5, 3.0]

而不是添加1,2,3,并获得平均6/3 = 2,我希望它添加1,1,0(每个列表中的第一个值)并得到2/2 = 1(如果为0,不算数) 我如何让循环来做呢?

5 个答案:

答案 0 :(得分:0)

您可以先使用zip

转换列表
zip(*listoflists)
>>> [(1, 1, 0), (2, 0, 5), (3, 4, 1)]

以下是一种方法:

final = []
for l in zip(*listoflists):
    final.append(float(sum(l)) / len([x for x in l if x != 0]))
print final

答案 1 :(得分:0)

你可以使用NumPy。

arr = np.array(listoflists)
sums = arr.sum(axis=0)
final = []    
for i in range(arr.shape[1]):
    final.append(sums[i]/np.count_nonzero(arr[:,i])

或者更好地完全避免循环。

arr = np.array(listoflists)
sums = arr.sum(0)
non_zeros = (arr != 0).sum(0)
final = sums / zon_zeros

答案 2 :(得分:0)

这对你有用:

p

编辑:    另一种方法是使用list comprehension和zip:

T

答案 3 :(得分:0)

from __future__ import division
map(lambda *column: sum(column)/sum(x>0 for x in column), *listoflists)

另一种可能性(仅限Python 3):

from statistics import mean
[mean(filter(None, column)) for column in zip(*listoflists)]

替代numpy实现(也适用于Python 2):

import numpy as np
a = np.array(listoflists)
np.average(a, axis=0, weights=a>0)

答案 4 :(得分:0)

让我们改进你的代码,使其更像Python。在Python中,我们可以迭代(遍历列表)并直接返回对象,我们并不需要使用索引。

final = []
for i in listoflists:
    count = 0
    val = 0

    for j in i:
        if j != 0:
            count += 1
            val += j 
    final.append(float(val)/count)

print final

此代码与没有索引的代码完全相同,j是我们获得的实际子项(数字)。

为了做你想做的事,Python有一个方便的zip()函数来转置子列表。例如,如果我们在[1,2] , [3,4]这些列表时有以下列表zip([1,2],[3,4]),我们会得到[(1, 3), (2, 4)]

我们可以通过使用列表列表前面的*符号解压缩列表来使用此功能来执行您想要的操作,zip()支持此功能。回到上一个示例,我们可以列出列表x = [[1,2],[3,4]]并将带有*的x传递到zip中以获得我们想要的内容。 zip(*x)我们会[(1, 3), (2, 4)]。将这些与您所拥有的结合在一起将为您提供所需的结果。

final = []
for i in zip(*listoflists):
    count = 0
    val = 0

    for j in i:
        if j != 0:
            count += 1
            val += j 
    final.append(float(val)/count)

我们可以通过使用sum()之类的更多功能来更好地改进这一点,如果可能的话,它会总结列表中的所有项目,并且您已经知道len()可以使用filter()过滤掉0。来自文档:

  如果函数为None,则

(项目中的项目为iterable if item)。

因此,我们检查列表是否包含有价值的项目,0

if 0:失败
final = []
for i in zip(*listoflists):
    if i: 
        final.append(float(sum(i))/len(filter(None, i)))
print final

我们可以更进一步,通过使用Python提供的最新功能之一来压缩函数,list comprehensions

print [float(sum(i))/len(filter(None,i)) for i in zip(*listoflists)]

请注意,其中一些答案可能不如其他答案最佳,但我的答案主要集中在只有内置插件才能实现的不同方法。