0

所以我的主要目标很简单,我希望在使用单个键时返回多个值。但是,我遇到了错误和令人困惑的行为。我是 Python 新手,所以我完全希望这个问题有一个简单的原因。

我有一个对象列表,list其中仅包含对象的索引。IE

1
2
3
4 
etc.. 

和一个文件,其中包含每个对象所属的组,以相同的顺序列出。该文件是 n 行的单个值(n 也是对象列表的长度。)即文件如下所示:

2
5
2
4
etc..

这意味着第一个对象属于第 2 组,第 5 组中的第二个对象,第 2 组中的第三个和第 4 组中的第四个。这个文件将根据我的输入文件而改变。我尝试了以下两个建议(我可以找到)。

编辑:我的最终目标:拥有一个字典,其中组号作为键,组中的对象作为值。

我首先查看了这个 StackOverflow问题以寻求帮助,因为它非常相似,最后得到了以下代码:

def createdDict(list, file): 

    f = open(file, 'r')
    d={}
    i=0 

    for line in f:
        groupIndex = int(line)
        if groupIndex in d:
            d[groupIndex].append(list[i])
        else:
            d[groupIndex] = list[i]
        i +=1
    print d
    f.close()

而这个错误:

AttributeError: 'Element' object has no attribute 'append'

d[groupIndex]只是一个字典和它的键,groupIndex也应该是一个整数.. 不是我在脚本前面创建的类中的对象。(为什么会出现这个错误?)

然后我在遇到另一个问题后修改了我的代码,如下所示,因为我认为这是完成我的任务的另一种方法。然后我的代码如下所示:

def createdDict(list, file): 

    f = open(file, 'r')
    d={}
    i=0 

    for line in f:
        groupIndex = int(line)
        if groupIndex in d:
            d.setdefault('groupIndex', []).append(list[i])
        else:
            d[groupIndex] = list[i]
        i +=1
    print d
    f.close()

此代码片段不会以错误或我想要的结尾,而是(我相信)是组中的最后一个对象......所以print d给了我钥匙和放在组中的最后一个对象(而不是想要的: 该组中的所有对象),然后终端随机吐出,groupIndex然后是list.

我的问题:我到底错过了什么?人们对我链接的问题的答案表示赞同,因此它们很可能是正确的,而我很可能错误地实施了它们。我不需要对这两个过程进行更正,但是对于我将多个值附加到一个键的问题的最有效答案。完成这项任务的最蟒蛇方式是什么?

编辑2:如果这有帮助,这里是第一个方法也引用错误的类。我不知道它是如何将此代码的任何部分定义为此类的一部分。我还没有真正开发它,但我完全是为了一个答案,所以如果这有助于定位错误:

class Element(object):
    def __init__(self, globalIndex):
        self.globalIndex = globalIndex
    def GetGlobalIndex (self):
        return self.globalIndex

globalIndex是对象(元素)的单独索引。对于我目前的问题,我正在列出这些元素的列表(这是前面提到的列表)并根据我的文件将它们分组为更小的组(也前面提到过)。为什么我认为这无关紧要,该列表本质上是整数的计数......它会如何与我的代码混淆?

4

4 回答 4

6

你的问题的基础是在这一行:

d[groupIndex] = list[i]

换句话说,当一个键不在字典中时,您在该键下添加一个Element对象)。下次您看到该键时,您尝试附加到该单个值。但是您不能附加到单个值。您需要一个容器类型(例如列表)来追加。Python 不会神奇地将你的Element对象变成一个列表!

解决方案很简单。如果您希望字典的值是列表,请执行此操作。添加第一项时,附加一个元素列表:

d[groupIndex] = [list[i]]

或者,您可以从原始列表中提取一项。这已经是一个列表了。

d[groupIndex] = list[i:i+1]

现在字典的值始终是列表,您可以将第二个和后续值附加到它们而不会出错。

正如ecatmur指出的那样,您可以if使用d.setdefault(groupIndex, []).append(list[i]). 如果键不存在,则该值将被视为一个空列表,您只需始终附加新项目。你也可以使用collections.defaultdict(list).

于 2012-07-09T19:40:40.997 回答
2

只需使用

d.setdefault(groupIndex, []).append(list[i])

这将检查是否groupIndexin d,因此您不需要该if groupIndex in d:行。

于 2012-07-09T19:37:13.803 回答
2
from itertools import izip
from collections import defaultdict

dd = defaultdict(list)
with open('filename.txt') as fin:
    for idx, line in izip(my_list, fin):
        num = int(line)
        defaultdict[num].append(idx)

这将创建defaultdict具有默认类型列表的 a,因此您可以在不使用的情况下追加setdefault. my_list然后从文件中读取与相应行组合的每个元素,将行转换为整数,然后将num相应的索引添加到组(由 表示)。

于 2012-07-09T19:40:49.033 回答
1

在您的第一次尝试中,您似乎正确理解将第一个元素添加到字典项是一种特殊情况,并且您还不能追加,因为字典项还没有值。

在您的情况下,您将其设置为 list[i]。但是, list[i] 不是列表,因此您不能在以后的迭代中对其运行 append。

我会做类似的事情:

for line in f:
    groupIndex = int(line)
    try:
        blah = d[groupIndex] # to check if it exists
    except:
        d[groupIndex] = [] # if not, assign empty list

    d[groupIndex].append(list[i])
print d
f.close()
于 2012-07-09T19:42:12.383 回答