Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何获取具有特定元素的列表的数量?_Python_List_Python 3.x_Counting - Fatal编程技术网

Python 如何获取具有特定元素的列表的数量?

Python 如何获取具有特定元素的列表的数量?,python,list,python-3.x,counting,Python,List,Python 3.x,Counting,我有一个列表,看起来像 listOfLists = [ ['a','b','c','d'], ['a','b'], ['a','c'], ['c','c','c','c'] ] 我想计算具有特定元素的列表的数量。例如,我的输出应该是 {'a':3,'b':2,'c':3,'d':1} 如您所见,我不需要元素的总计数。对于“c”,虽然其总计数为5,但输出为3,因为它只出现在3个列表中 我正在用计数器来计数。下面可以看到同样的情况 line_count_t

我有一个列表,看起来像

listOfLists = [
    ['a','b','c','d'],
    ['a','b'],
    ['a','c'],
    ['c','c','c','c']  
 ] 
我想计算具有特定元素的列表的数量。例如,我的输出应该是

{'a':3,'b':2,'c':3,'d':1}
如您所见,我不需要元素的总计数。对于
“c”
,虽然其总计数为5,但输出为3,因为它只出现在3个列表中

我正在用计数器来计数。下面可以看到同样的情况

line_count_tags = []
for lists in lists_of_lists:
    s = set()
    for element in lists:
         s.add(t)
    lines_count_tags.append(list(s))

count = Counter([count for counts in lines_count_tags for count in counts])
所以,当我打印计数时,我得到

{'a':3,'c':3,'b':2,'d':1}

我想知道是否有更好的方法来实现我的目标。

我会将每个列表转换为一组,然后在传递给
计数器的生成器中进行计数:

import collections
print(collections.Counter(y for x in listOfLists for y in set(x)))
>>> from collections import Counter
>>> from itertools import chain

>>> Counter(chain.from_iterable(map(set, listOfLists)))
Counter({'a': 3, 'b': 2, 'c': 3, 'd': 1})
结果:

Counter({'a': 3, 'c': 3, 'b': 2, 'd': 1})
(这实际上就是您所做的,但是上面的代码缩短了许多循环和临时列表创建)

使用a并将每个列表转换为一个集合。
集合
将从每个列表中删除任何重复项,这样您就不会对同一列表中的重复值进行计数:

>>> from collections import Counter

>>> Counter(item for lst in listOfLists for item in set(lst))
Counter({'a': 3, 'b': 2, 'c': 3, 'd': 1})
如果您喜欢函数式编程,还可以将
集合的
-
映射
ped
列表
馈送到
计数器

import collections
print(collections.Counter(y for x in listOfLists for y in set(x)))
>>> from collections import Counter
>>> from itertools import chain

>>> Counter(chain.from_iterable(map(set, listOfLists)))
Counter({'a': 3, 'b': 2, 'c': 3, 'd': 1})

这与第一种方法完全相同(除了可能快一点之外)。

您也可以在不使用
计数器的情况下执行此操作:

result = {}
for lis in listOfLists:
    for element in set(lis):
        result[element] = result.get(element, 0) + 1
print result  # {'a': 3, 'c': 3, 'b': 2, 'd': 1}

这不是最优雅的,但应该要快得多。

计数器上有一点风格上的差异

Counter(chain.from_iterable(map(set, listOfLists)))
演示

>>> from itertools import chain
>>> from collections import Counter
>>> Counter(chain.from_iterable(map(set, listOfLists)))
Counter({'a': 3, 'b': 2, 'c': 3, 'd': 1})

粗略基准

%timeit Counter(item for lst in listOfLists for item in set(lst))
100000 loops, best of 3: 13.5 µs per loop

%timeit Counter(chain.from_iterable(map(set, listOfLists)))
100000 loops, best of 3: 12.4 µs per loop

只需转换到
set
,使用
itertools.chain.from\u iterable
展平,然后送入
计数器

from collections import Counter
from itertools import chain

inp = [
    ['a','b','c','d'],
    ['a','b'],
    ['a','c'],
    ['c','c','c','c']  
 ] 


print(Counter(chain.from_iterable(map(set, inp))))

这种方法使用集合理解计算列表中的唯一条目,然后使用字典理解计算每个列表中的出现次数

A = {val for s in listOfLists for val in s}
d = {i: sum( i in j for j in listOfLists) for i in A}
print(d) # {'a': 3, 'c': 3, 'b': 2, 'd': 1}
我承认这有点难看,但这是一个可能的解决办法(而且是对词典理解的一种很酷的使用)。
您还可以通过将
a
的计算右移到字典理解中,使其成为一行,这里是另一个使用循环的版本:

A = {val for s in listOfLists for val in s}
d = {i: sum( i in j for j in listOfLists) for i in A}
print(d) # {'a': 3, 'c': 3, 'b': 2, 'd': 1}
listOfLists = [
    ['a','b','c','d'],
    ['a','b'],
    ['a','c'],
    ['c','c','c','c']
    ]

final = {}
for lst in listOfLists:
    for letter in lst:
        if letter in final:
            final[letter] += 1
        else:
            final[letter] = 1

因此,创建一个名为final的空字典。然后循环浏览每个列表的每个字母。创建一个新键,如果字母还没有作为键存在于final中,则值=1。否则,为该键的值添加1。

无需再次将集合
A
强制转换为列表,也无需向集合提供列表理解,生成表达式更好。。。实际上,您可以将
A
构建为一个集合too@Copperfield谢谢你的建议。我做了一个改变。我在CPython 2.7.11上使用
itertools.chain
(~40%!)获得了更快的执行速度。不过,
计数器
+
itertools.chain
执行速度比我介绍的
raw
方法慢4倍。@zwer-Eh,取决于我们讨论的输入大小。我的解决方案有更多的开销,但如果您增加输入大小,它会更快。这就是为什么基准测试并不太重要:)没错,我只是对我所在的位置在速度上的巨大差异感到惊讶,我不习惯
itertools
实际上比任何东西都好——它们通常是速度较慢但更容易阅读的选择:D