所以我有一个字符串列表:
list1 = ["1thing", "2thing", "3thing", "1thing"]
我想了解列表中每个元素出现的次数。问题是,我只想比较前几个字符,因为我知道如果前面3个字符相同,那么整个字符串就相同。我在考虑修改内置的list.count(x)方法,或者覆盖__eq__
运算符,但我不知道该如何实现。
所以我有一个字符串列表:
list1 = ["1thing", "2thing", "3thing", "1thing"]
我想了解列表中每个元素出现的次数。问题是,我只想比较前几个字符,因为我知道如果前面3个字符相同,那么整个字符串就相同。我在考虑修改内置的list.count(x)方法,或者覆盖__eq__
运算符,但我不知道该如何实现。
使用生成器提取前几个字符,并在其上使用内置的 collections.Counter
类:
Counter(item[:2] for item in list1)
为什么要费劲地去做,可以使用collections.Counter
模块来查找频率。
>>> import collections
>>> x=['1thing', '2thing', '1thing', '3thing']
>>> y=collections.Counter(x)
>>> y
Counter({'1thing': 2, '2thing': 1, '3thing': 1})
这可能不如@Marcin的解决方案好,但使用itertools.groupby
可以使其更易读和灵活。
from itertools import groupby
def group_by_startswith(it, n):
"""Get a dict mapping the first n characters to the number of matches."""
def first_n(str_):
return str_[:n]
startswith_sorted = sorted(it, key=first_n)
groups = groupby(startswith_sorted, key=first_n)
return {key: len(list(grouped)) for key, grouped in groups}
例子输出:
>>> list1 = ["1thing", "2thing", "3thing", "1thing"]
>>> print(group_by_startswith(list1, 3))
{'3th': 1, '2th': 1, '1th': 2}
这个方案使结果具有更多的灵活性。例如,修改返回行以返回grouped
或list(grouped)
,可以轻松获取匹配的对象。
map
)时,对将函数映射到一系列值上进行一些不必要的强调(在我看来,当您有一个更复杂的映射函数时,这样做更好)。 - Casey Kuball