python 按字母获取列表元素

0 投票
6 回答
696 浏览
提问于 2025-04-17 22:48

我有一个按字母顺序排列的名字列表,比如:

list = ['ABC', 'ACE', 'BED', 'BRT', 'CCD', ..]

我该怎么从每个字母开头的名字中获取一个元素呢?我需要遍历这个列表一次吗?还是说Python有什么函数可以做到这一点?我刚接触Python,这可能是个很简单的问题。

假设我想从以'A'开头的名字中获取第二个元素,这样我就能得到'ACE'。

6 个回答

0

简单的解决办法是遍历整个列表,时间复杂度是 O(n)

(name for name in names if name.startswith('A'))

不过,你也可以先把名字排序,然后用 O(log(n)) 的时间来查找应该在某个索引位置或之后的项目(使用字典序比较)。可以使用 bisect 模块来帮助你找到边界:

from bisect import bisect_left

names = ['ABC', 'ACE', 'BED', 'BRT', 'CCD']

names.sort() 

lower = bisect_left(names, 'B')
upper = bisect_left(names, chr(1+ord('B')))

print [names[i] for i in range(lower, upper)] 
# ['BED', 'BRT']
0

你可能想要使用列表推导式

mylist = ['ABC', 'ACE', 'BED', 'BRT', 'CCD']
elements_starting_with_A = [i for i in mylist if i[0] == 'A']
>>> ['ABC', 'ACE']
second = elements_starting_with_A[1]
>>> 'ACE'
1

简单来说,就是把所有的元素按照它们的第一个字符分组。

from itertools import groupby
from operator import itemgetter

example = ['ABC', 'ACE', 'BED', 'BRT', 'CCD']


d = {g:list(values) for g, values in groupby(example, itemgetter(0))}

现在我们来获取一个以'a'开头的值:

print d.get('A', [])

这个方法特别适合当你有一个固定的列表,并且会进行多次查询。因为你可以看到,获取以'A'开头的第三个项目是非常快速的,只需要O(1)的时间。

3

使用生成器表达式itertools.islice

>>> import itertools
>>> names = ['ABC', 'ACE', 'BED', 'BRT', 'CCD']
>>> next(itertools.islice((name for name in names if name.startswith('A')), 1, 2), 'no-such-name')
'ACE'

>>> names = ['ABC', 'BBD', 'BED', 'BRT', 'CCD']
>>> next(itertools.islice((name for name in names if name.startswith('A')), 1, 2), 'no-such-name')
'no-such-name'
3

如果你打算进行多次搜索,最好先花点时间把所有东西都遍历一遍,然后建立一个字典(或者为了简单起见,可以用 collections.defaultdict):

from collections import defaultdict

d = defaultdict(list)

words = ['ABC', 'ACE', 'BED', 'BRT', 'CCD', ...]

for word in words:
    d[word[0]].append(word)

(注意,不要把你自己的变量命名为 list,因为这样会覆盖掉内置的列表功能。)

现在你可以轻松地查询以 "A" 开头的第二个单词:

d["A"][1] == "ACE"

或者查询每个字母的前两个单词:

first_two = {c: w[:2] for c, w in d.items()}

撰写回答