如何将这个元组的元组转换为其元素的计数?

3 投票
2 回答
1009 浏览
提问于 2025-04-18 10:39

我有一个包含多个元组的元组:

TupleOfTuples = (('Venue1', 'Name1'), ('Venue1', 'Name2'), 
                 ('Venue2', 'Name3'), ('Venue3', 'Name4'), 
                 ('Venue3', 'Name5'), ('Venue3', 'Name6'))

我想把它转换成这样的结果:

Output = (('Venue1', 2), ('Venue2', 1), ('Venue3', 3))

在这个例子中,Output 包含 ('Venue1', 2),其中 2'Venue1'TupleOfTuples 中出现的次数。

我试着用 len() 来计算出现的次数,但由于 TupleOfTuples 不是一个单独的元组,而是一个元组的元组,所以这样做不行。

在 Python2.7 中,我该怎么做呢?

2 个回答

1

你可以很快很简单地用 zip(*TupleOfTuples)[n] 来获取所有要计数的元素序列(这里的 n 是你想要计数的每个 TupleOfTuples 元组中的元素索引;在这个例子中是 0),然后遍历结果来统计每个独特元素的数量。

下面是具体的代码示例:

TupleOfElements = zip(*TupleOfTuples)[0]
Output = tuple((e, TupleOfElements.count(e)) for e in set(TupleOfElements))

我来解释一下这个过程:

zip(*TupleOfTuples)[0] 会把你的输入序列进行 转置。我们想要每个 TupleOfTuples 元组中的第一个元素,所以从结果中取 [0]。我们把这个序列赋值给 TupleOfElements。如果你想要统计 Name* 元素的话,可以用 zip(*TupleOfTuples)[1]

tuple((e, TupleOfElements.count(e)) for e in set(TupleOfElements)) 通过遍历 TupleOfElements 来创建你想要的 Output,为每个独特元素返回一个元素-计数对:TupleOfElements 包含了 所有 TupleOfTuples 元素的正确数量,所以我们可以用 TupleOfElements.count(uniqueElement) 来告诉我们 uniqueElement 出现了多少次。不过,我们不需要也不想对任何特定元素检查超过一次,所以我们遍历 set(TupleOfElements),这个集合中每个元素只会出现一次。最后,我们把结果赋值给 Output,就完成了!

  • 注意:这个结果会返回一个 tuple。如果你想要一个 list,只需把第二行的 tuple(..) 替换成 [..],内容保持不变。

  • 关于性能:这段代码运行速度似乎比 Martijn 使用 collections.Counter 的非常好的解决方案快很多——在给定的例子 TupleOfTuples 中快了大约 3.5 倍,而在我自己为了好奇而做的一个更大但更简单的 88,888 元素测试中快了大约 1.25 倍——我想这可能是因为它用元组和迭代器替代了字典创建的步骤。虽然它可能没有那么优雅,但我还是对此有点自豪。

5

使用 collections.Counter() 可以帮你计算某个东西出现了多少次:

from collections import Counter

Output = Counter(t[0] for t in TupleOfTuples).items()

Counter() 是一种字典,里面的键对应着出现的次数;你只需要传入一个生成器表达式,它就会自动帮你数了。因为它是字典的一个子类,所以你可以用 dict.items() 来生成一个 (键, 次数) 的列表。

这样会生成一个 列表;如果你一定想要元组,可以直接在这个列表上调用 tuple()

示例:

>>> from collections import Counter
>>> TupleOfTuples = ( ('Venue1', 'Name1'), ('Venue1', 'Name2'), ('Venue2', 'Name3'), ('Venue3', 'Name4'), ('Venue3', 'Name5'), ('Venue3', 'Name6') )
>>> Counter(t[0] for t in TupleOfTuples).items()
[('Venue1', 2), ('Venue3', 3), ('Venue2', 1)]

撰写回答