我有一份长度等于[l1, ..., ln]
的列表l
我想比较l1[k], l2[k], ..., ln[k]
中所有k
的{{1}},并通过选择最常出现的元素来制作另一个列表len(l1)
。
所以,如果是l0
,l1 = [1, 2, 3]
和l2 = [1, 4, 4]
,那么l3 = [0, 2, 4]
。如果存在平局,我将查看构成平局的列表,并选择列表中具有更高优先级的列表。优先权是先验的,每个清单都有优先权。
防爆。如果您在列表l = [1, 2, 4]
和l1
中有值1,在列表l3
和l2
中有值2,在l4
中有3,并且列表是根据优先级,比如说l5
,然后我会选择2,因为2位于l5>l2>l3>l1>l4
,其中包含一个出现次数最多的元素,其优先级高于l2
和l1
。
如何在没有创建包含大量if / else条件的for循环的情况下在python中执行此操作?
答案 0 :(得分:4)
您可以使用集合库中的Counter模块。使用map
函数将减少列表循环。对于没有最常见值但仅限于此的情况,您将需要if / else语句:
import collections
list0 = []
list_length = len(your_lists[0])
for k in list_length:
k_vals = map(lambda x: x[k], your_lists) #collect all values at k pos
counts = collections.Counter(k_vals).most_common() #tuples (val,ct) sorted by count
if counts[0][1] > counts[1][1]: #is there a most common value
list0.append(counts[0][0]) #takes the value with highest count
else:
list0.append(k_vals[0]) #takes element from first list
list0
是您正在寻找的答案。我只是讨厌使用l
,因为它很容易与数字1
混淆
修改(根据评论):
合并你的注释而不是if / else语句,使用while循环:
i = list_length
while counts[0][1] == counts[1][1]:
counts = collections.Counter(k_vals[:i]).most_common() #ignore the lowest priority element
i -= 1 #go back farther if there's still a tie
list0.append(counts[0][0]) #takes the value with highest count once there's no tie
所以现在整个事情都是:
import collections
list0 = []
list_length = len(your_lists[0])
for k in list_length:
k_vals = map(lambda x: x[k], your_lists) #collect all values at k pos
counts = collections.Counter(k_vals).most_common() #tuples (val,ct) sorted by count
i = list_length
while counts[0][1] == counts[1][1]: #in case of a tie
counts = collections.Counter(k_vals[:i]).most_common() #ignore the lowest priority element
i -= 1 #go back farther if there's still a tie
list0.append(counts[0][0]) #takes the value with highest count
你再投入一个微小的循环,但在光明的一面,根本没有if / else语句!
答案 1 :(得分:3)
只需转置子列表并从每个组中获取Counter.most_common
元素键:
l1, l2, l3 = [1, 2, 3], [1, 4, 4], [0, 2, 4]
print([Counter(sub).most_common(1)[0][0] for sub in zip(l1,l2,l3)])
如果他们是个人名单,只需输入:
def most_cm(lists):
for sub in zip(*lists):
# get two most frequent
comm = Counter(sub).most_common(2)
# if their values are equal just return the ele from l1
yield comm[0][0] if len(comm) == 1 or comm[0][1] != comm[1][1] else sub[0]
不确定如果存在平局,如何从分组中获取第一个元素是有意义的,因为它可能不是那个并列但实现起来很简单的元素,只需获取两个最常见的并检查它们的计数是否相等:< / p>
if len(comm) == 1
我们还需要In [61]: lis = [[randint(1,10000) for _ in range(10)] for _ in range(100000)]
In [62]: list(most_cm(lis))
Out[62]: [5856, 9104, 1245, 4304, 829, 8214, 9496, 9182, 8233, 7482]
In [63]: timeit list(most_cm(lis))
1 loops, best of 3: 249 ms per loop
,以防所有元素都相同或者我们会得到一个IndexError。
如果你正在谈论在并列事件中采用来自早期列表的元素,即l5在l5之前,那么这与采用任何相关的元素相同。
对于相当数量的子列表:
{{1}}
答案 2 :(得分:2)
解决方案是:
a = [1, 2, 3]
b = [1, 4, 4]
c = [0, 2, 4]
print [max(set(element), key=element.count) for element in zip(a, b, c)]
答案 3 :(得分:2)
这就是你要找的东西:
from collections import Counter
from operator import itemgetter
l0 = [max(Counter(li).items(), key=itemgetter(1))[0] for li in zip(*l)]
答案 4 :(得分:2)
如果你可以选择最常见的一组元素中的任何一个,并且你可以保证你不会在列表列表中找到一个空列表,那么这是一种使用{{1 (所以,Counter
):
from collections import Counter
在IPython中执行此操作并打印结果:
l = [ [1, 0, 2, 3, 4, 7, 8],
[2, 0, 2, 1, 0, 7, 1],
[2, 0, 1, 4, 0, 1, 8]]
res = []
for k in range(len(l[0])):
res.append(Counter(lst[k] for lst in l).most_common()[0][0])
答案 5 :(得分:1)
试试这个:
l1 = [1,2,3]
l2 = [1,4,4]
l3 = [0,2,4]
lists = [l1, l2, l3]
print [max(set(x), key=x.count) for x in zip(*lists)]