我在
列表中嵌套了元组l = [(1, 'a', 'b'), (2, 'b', 'c'), (3, 'e', 'a')]
我想知道列表中有多少'a'和'b'。所以我目前使用以下代码来获得结果。
amount_a_and_b = len([None for _, elem2, elem3 in l if elem2 == 'a' or elem3 == 'b'])
但我得到了amount_a_and_b = 1
,那么如何得到正确答案?
此外,是否有更优雅的方式(更少的代码或更高的性能或使用内置)来做到这一点?
答案 0 :(得分:6)
我将列表展开为itertools.chain.from_iterable()
并将其传递给collections.Counter()
object:
from collections import Counter
from itertools import chain
counts = Counter(chain.from_iterable(l))
amount_a_and_b = counts['a'] + counts['b']
或使用sum()
计算值在展平序列中出现的次数:
from itertools import chain
amount_a_and_b = sum(1 for v in chain.from_iterable(l) if v in {'a', 'b'})
在我的Macbook Pro(OS X 10.11)上,这两种方法在Python 3.5.1上的速度非常可比:
>>> from timeit import timeit
>>> from collections import Counter
>>> from itertools import chain
>>> l = [(1, 'a', 'b'), (2, 'b', 'c'), (3, 'e', 'a')] * 1000 # make it interesting
>>> def counter():
... counts = Counter(chain.from_iterable(l))
... counts['a'] + counts['b']
...
>>> def summing():
... sum(1 for v in chain.from_iterable(l) if v in {'a', 'b'})
...
>>> timeit(counter, number=1000)
0.5640139860006457
>>> timeit(summing, number=1000)
0.6066895100011607
答案 1 :(得分:1)
您希望避免将数据放入数据结构中。 [...]
语法构造一个新列表并使用您放在...
中的内容填充它,之后将获取数组的长度并且从不使用该数组。如果列表非常大,这会占用大量内存,而且通常不够优雅。您还可以使用迭代器循环遍历现有数据结构,例如:
sum(sum(c in ('a', 'b') for c in t) for t in l)
c in ('a', 'b')
谓词是一个bool,在转换为int时计算结果为0或1,导致sum()
仅在谓词计算为True
时计算元组条目。
答案 2 :(得分:0)
只是为了好玩,使用reduce的功能方法:
>>> l = [(1, 'a', 'b'), (2, 'b', 'c'), (3, 'e', 'a')]
>>> from functools import reduce
>>> reduce(lambda x, y: (1 if 'a' in y else 0) + (1 if 'b' in y else 0) + x, l, 0)
4
答案 3 :(得分:0)
您可以在一个列表解析中迭代列表和子列表:
len([i for sub_list in l for i in sub_list if i in ("a", "b")])
我认为这很简洁。
为避免创建临时列表,您可以使用生成器表达式创建1的序列并将其传递给sum
:
sum(1 for sub_list in l for i in sub_list if i in ("a", "b"))
答案 4 :(得分:0)
虽然这个问题已经有了一个公认的答案,但只是想知道为什么所有这些问题都如此复杂。我认为这就足够了。
>>> l = [(1, 'a', 'b'), (2, 'b', 'c'), (3, 'e', 'a')]
>>> total = sum(tup.count('a') + tup.count('b') for tup in l)
>>> total
4
或者
>>> total = sum(1 for tup in l for v in tup if v in {'a', 'b'})