在Python中,有办法根据容器元素索引容器列表(元组、列表、字典)吗?
我一直在寻找一个方法,想要给一组元组建立索引,但不想用那种“装饰-排序-去装饰”的方法。
举个例子:
l=[(a,b,c),(x,c,b),(z,c,b),(z,c,d),(a,d,d),(x,d,c) . . .]
我现在用的方法是,利用defaultdict来创建一个字典,字典的键是元组的第二个元素。
from collections import defaultdict
tdict=defaultdict(int)
for myTuple in l:
tdict[myTuple[1]]+=1
接着,我需要建立一个只包含每个元组第二个元素的列表。虽然有很多方法可以做到这一点,但一个简单的方法是:
tempList=[myTuple[1] for myTuple in l]
然后生成一个包含tdict中每个项目索引的列表。
indexDict=defaultdict(dict)
for key in tdict:
indexDict[key]['index']=tempList.index(key)
显然,这种做法看起来并不太符合Python的风格。我一直在寻找一些例子或灵感,想着应该能用一些神奇的方法直接获取索引,但到现在为止还没有找到。
需要注意的是,我明白我可以更直接地处理,而不需要生成tdict。
输出可以是一个带有索引的字典。
indexDict={'b':{'index':0},'c':{'index':1},'d':{'index':4},. . .}
在从Nadia的回答中学到了很多之后,我觉得答案是否定的。
虽然她的回答是可行的,但我觉得比需要的要复杂。我会简单地
def build_index(someList):
indexDict={}
for item in enumerate(someList):
if item[1][1] not in indexDict:
indexDict[item[1][1]]=item[0]
return indexDict
2 个回答
0
如果我理解你的意思没错的话……
l = ['asd', 'asdxzc']
d = {}
for i, x in enumerate(l):
d[x] = {'index': i}
5
这段代码会生成你想要的结果。
dict((myTuple[1], index) for index, myTuple in enumerate(l))
>>> l = [(1, 2, 3), (4, 5, 6), (1, 4, 6)]
>>> dict((myTuple[1], index) for index, myTuple in enumerate(l))
{2: 0, 4: 2, 5: 1}
如果你坚持用字典来表示索引的话:
dict((myTuple[1], {'index': index}) for index, myTuple in enumerate(l))
那么结果将会是:
{2: {'index': 0}, 4: {'index': 2}, 5: {'index': 1}}
编辑
如果你想处理键冲突的问题,那你需要像这样扩展解决方案:
def build_index(l):
indexes = [(myTuple[1], index) for index, myTuple in enumerate(l)]
d = {}
for e, index in indexes:
d[e] = min(index, d.get(e, index))
return d
>>> l = [(1, 2, 3), (4, 5, 6), (1, 4, 6), (2, 4, 6)]
>>> build_index(l)
{2: 0, 4: 2, 5: 1}
编辑 2
还有一个更通用且简洁的解决方案(类似于sorted的定义)
def index(l, key):
d = {}
for index, myTuple in enumerate(l):
d[key(myTuple)] = min(index, d.get(key(myTuple), index))
return d
>>> index(l, lambda a: a[1])
{2: 0, 4: 2, 5: 1}
所以你问的问题的答案是肯定的:在Python中,有一种方法可以通过容器中的一个元素来索引一组容器(元组、列表、字典),而不需要预处理。不过,你要求把结果存储在字典里,这样就不能用一行代码实现。但这里没有预处理,列表只会被遍历一次。