我有一个按字母顺序排列的名称列表,例如:
list = ['ABC', 'ACE', 'BED', 'BRT', 'CCD', ..]
如何从每个起始字母中获取元素?我必须迭代一次列表吗?或者 python 是否有一些功能可以做到这一点?python新手,这可能是一个非常幼稚的问题。
假设我想从以“A”开头的名称中获取第二个元素,这种情况下我得到“ACE”。
>>> 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'
如果你要进行多次搜索,你应该一次性遍历所有内容并构建一个字典(或者,为了更简单,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()}
只需按第一个字符对所有元素进行分组
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) 中完成的
简单的解决方案是遍历整个列表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']
您可能想要使用列表推导
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'
除了其他人提到的列表理解之外,列表还有一种sort()
方法。
mylist = ['AA', 'BB', 'AB', 'CA', 'AC']
newlist = [i for i in mylist if i[0] == 'A']
newlist.sort()
newlist
>>> ['AA', 'AB', 'AC']