【发布时间】:2018-02-15 07:09:23
【问题描述】:
我正在努力编写一个函数,该函数将遍历数字列表[2, 4, 3, 2, 2] 并重新计算重复项的值,以便此示例中的所有 2 相加(=6),然后除以长度的名单。长度 = 5。
输出:[6/5, 4, 3, 6/5, 6/5]
每个数字都必须保持原位,输入列表中的数字可以是正数和负数。 关于如何处理的任何想法?
【问题讨论】:
标签: python list duplicates average
我正在努力编写一个函数,该函数将遍历数字列表[2, 4, 3, 2, 2] 并重新计算重复项的值,以便此示例中的所有 2 相加(=6),然后除以长度的名单。长度 = 5。
输出:[6/5, 4, 3, 6/5, 6/5]
每个数字都必须保持原位,输入列表中的数字可以是正数和负数。 关于如何处理的任何想法?
【问题讨论】:
标签: python list duplicates average
首先,让我们导入 Counter 并定义您的列表:
>>> from collections import Counter
>>> x = [2, 4, 3, 2, 2]
其次,我们创建ctr,Counter 的一个实例,它将包含每个元素在您的列表中出现的次数:
>>> ctr = Counter(x)
最后,让我们创建您想要的新列表:
>>> [i if ctr[i]==1 else ctr[i]*i/len(x) for i in x]
[1.2, 4, 3, 1.2, 1.2]
i if ctr[i]==1 else ctr[i]*i/len(x) 是一个三元语句。如果i 仅在x 中出现一次,则计算结果为i。否则,它的计算结果为i 乘以i 在x 中出现的次数除以x 的长度:ctr[i]*i/len(x)。
【讨论】:
您可以使用列表推导
例如:
t = [2, 4, 3, 2, 2]
print [float(i * t.count(i)) / float(len(t)) if t.count(i) > 1 else i for i in t]
输出:
[1.2, 4, 3, 1.2, 1.2]
【讨论】:
1 != 6/5.
Fraction(1.2).limit_denominator() 将有助于使答案更具体,就像 OP 提到的那样。它会给出6/5。
你可以先使用itertools.groupby对所有元素进行分组
>>> from itertools import groupby
>>> k = [(k,len(list(g)) for k,g in groupby(sorted(l))]
这将为您提供(element, frequency) 格式列表的每个元素的元组:
>>> [(2, 3), (3, 1), (4, 1)]
接下来从这个元组列表创建一个映射字典
>>> mapping = dict(k)
>>> mapping
>>> {2: 3, 3: 1, 4: 1}
现在替换原始列表中映射dict中的值大于1的所有元素
>>> [map[k]*k/len(l) if map[k] > 1 else k for k in l]
>>> [1.2, 4, 3, 1.2, 1.2]
【讨论】: