如何获取具有特定元素的列表的数量?
How do I get the number of lists with a particular element?
我有一个列表列表,看起来像
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}
我想知道是否有更好的方法来实现我的目标。
我会将每个列表转换为一个集合,然后再计算传递给 Counter
:
的生成器理解
import collections
print(collections.Counter(y for x in listOfLists for y in set(x)))
结果:
Counter({'a': 3, 'c': 3, 'b': 2, 'd': 1})
(这实际上就是您所做的,但是上面的代码减少了很多循环和临时列表的创建)
使用 Counter
并将每个列表转换为一个集合。 set
将从每个列表中删除任何重复项,这样您就不会计算同一列表中的重复值:
>>> from collections import Counter
>>> Counter(item for lst in listOfLists for item in set(lst))
Counter({'a': 3, 'b': 2, 'c': 3, 'd': 1})
如果您喜欢函数式编程,您还可以将 chain
的 set
-map
ped listOfLists
提供给 Counter
:
>>> 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
:
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
方法与 itertools.chain.from_iterable
的风格有点不同,可能看起来像
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_iterable
展平,然后输入 Counter
。
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))))
此方法使用集合推导计算 listOfLists
中的唯一条目,然后使用字典推导计算每个列表中的出现次数
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
的计算移到字典理解
中来使其成为 one-liner
这是另一个使用循环的版本:
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 添加到该键的值。
我有一个列表列表,看起来像
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}
我想知道是否有更好的方法来实现我的目标。
我会将每个列表转换为一个集合,然后再计算传递给 Counter
:
import collections
print(collections.Counter(y for x in listOfLists for y in set(x)))
结果:
Counter({'a': 3, 'c': 3, 'b': 2, 'd': 1})
(这实际上就是您所做的,但是上面的代码减少了很多循环和临时列表的创建)
使用 Counter
并将每个列表转换为一个集合。 set
将从每个列表中删除任何重复项,这样您就不会计算同一列表中的重复值:
>>> from collections import Counter
>>> Counter(item for lst in listOfLists for item in set(lst))
Counter({'a': 3, 'b': 2, 'c': 3, 'd': 1})
如果您喜欢函数式编程,您还可以将 chain
的 set
-map
ped listOfLists
提供给 Counter
:
>>> 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
:
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
方法与 itertools.chain.from_iterable
的风格有点不同,可能看起来像
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_iterable
展平,然后输入 Counter
。
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))))
此方法使用集合推导计算 listOfLists
中的唯一条目,然后使用字典推导计算每个列表中的出现次数
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
的计算移到字典理解
这是另一个使用循环的版本:
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 添加到该键的值。