【问题标题】:Is there a way in Python to index a list of containers (tuples, lists, dictionaries) by an element of a container?Python中有没有办法通过容器的元素来索引容器列表(元组、列表、字典)?
【发布时间】:2009-05-27 21:22:43
【问题描述】:

我一直在寻找一个配方/示例来索引元组列表,而无需修改装饰、排序、取消装饰方法。

例如:

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)

显然,这似乎不是很 Pythonic。我一直在尝试寻找示例或见解,认为我应该能够使用一些神奇的东西来直接获取索引。到目前为止还没有这样的运气。

注意,我知道我可以更直接地采用我的方法,而不是生成 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

【问题讨论】:

  • 我对你想要做什么感到困惑。你想要的输出是什么?您的代码无法正常工作——“tdict[myTuple[1]]+=count”行中的 count 应该是多少?
  • 你能提供一个预期输出或结构的例子吗?
  • 抱歉——每次我创建字典来获取项目的计数时,我总是先写 +=count,然后再将其更正为 +=1。我有一个脑细胞。

标签: python indexing list containers


【解决方案1】:

这会产生你想要的结果

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 中有一种方法可以通过容器的元素来索引容器列表(元组、列表、字典),而无需预处理。但是您将结果存储在字典中的要求使得它不可能成为一个单行。但是这里没有预处理。该列表仅迭代一次。

【讨论】:

  • 这很漂亮。我看到的是一个正确思考问题的问题。我看到这应该推广到容器列表中的任何子容器。很酷,谢谢
  • 实际上,Nadia 这很接近,但并不完全在那里。尝试再添加一个具有公共中间值的元组,例如 add (2,4,6),您会发现索引是最后一个值的枚举——当您写入字典时,您会覆盖这些值。但我认为它给了我足够的力量到达那里。我理解你的代码,因为我真的想创建一个 key 字典 begin: value end:value 我就在那里。
  • 我从你那里学到了很多,你的回答帮助我思考并更好地理解列表理解和字典。不过,您的回答表明我的问题的答案是否定的。如果不首先访问和操作要从中索引的容器,就不可能对包含一些容器对象的列表进行索引。
  • @PyNEwbie,我没有建议答案是否定的。除非您的问题是“python 中是否有一个内置函数可以做到这一点?”。有一个非常简单的 O(n) 解决方案。
【解决方案2】:

如果我认为这就是你要问的......

l = ['asd', 'asdxzc']
d = {}

for i, x in enumerate(l):
    d[x] = {'index': i}

【讨论】:

  • 为什么不使用枚举呢?
  • 不知道存在。让它变得相当简单。
  • 您的代码简单获取列表中每个唯一项的索引值,我想更精细地获取索引值。 Nadia 的代码有一个明确的答案。我认为不会有更好的解决方案。
  • 是的,我同意。在原始帖子的时候,我不太明白你想要什么,我认为它可能只是想要一个 for 循环的索引。
猜你喜欢
  • 1970-01-01
  • 2021-12-20
  • 2013-12-03
  • 2020-06-21
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 2014-07-08
  • 1970-01-01
相关资源
最近更新 更多