所以我的主要目标很简单,我希望在使用单个键时返回多个值.但是我遇到了错误和令人困惑的行为.我是Python的新手,所以我完全期望这个问题有一个简单的原因.
我有一个对象列表,list
它只包含对象的索引.即
1
2
3
4
etc..
Run Code Online (Sandbox Code Playgroud)
以及包含每个对象所属的组的文件,以相同的顺序列出.该文件是n行的单个值(n也是对象列表的长度.)即文件如下所示:
2
5
2
4
etc..
Run Code Online (Sandbox Code Playgroud)
意味着第一个对象属于组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()
Run Code Online (Sandbox Code Playgroud)
而这个错误:
AttributeError: 'Element' object has no attribute 'append'
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
这段代码片段并没有以错误或我想要的结尾,而是(我相信)是组中的最后一个对象...所以print d
给了我关键和放在组中的最后一个对象(而不是所需的:该组中的所有对象)然后终端随机吐出,groupIndex
然后是所有对象list
.
我的问题:我到底错过了什么?人们对我链接的问题的答案进行了评价,因此他们很可能是正确的,我可能会错误地实施它们.我不需要对这两个程序进行更正,但是对于将多个值附加到一个键的问题,最有效的答案.什么是完成这项任务的最pythonic方式?
编辑2:如果这有帮助,这里是第一种方法引用错误的类.我不知道它如何定义此代码的任何部分作为此类的一部分.我还没有真正开发它,但我只是为了答案,所以如果这有助于找到错误:
class Element(object):
def __init__(self, globalIndex):
self.globalIndex = globalIndex
def GetGlobalIndex (self):
return self.globalIndex
Run Code Online (Sandbox Code Playgroud)
globalIndex
是一个单独的对象索引(元素).根据我当前的问题,我正在列出这些元素(这是前面提到的列表),并根据我的文件将它们分组到较小的组中(前面也提到过).为什么我认为这不重要,列表基本上是整数的计数......我的代码会怎么样?
您的问题的基础在这一行:
d[groupIndex] = list[i]
Run Code Online (Sandbox Code Playgroud)
换句话说,当键不在字典中时,您在该键下添加单个值(Element
对象).下次看到该键时,您会尝试附加到该单个值.但是你不能附加单个值.您需要附加容器类型(例如列表).Python并没有神奇地将你的Element
对象变成一个列表!
解决方案很简单.如果您希望字典的值为列表,那么请执行此操作.添加第一个项目时,附加一个元素列表:
d[groupIndex] = [list[i]]
Run Code Online (Sandbox Code Playgroud)
或者,您可以获取原始列表的单项切片.这已经是一个清单了.
d[groupIndex] = list[i:i+1]
Run Code Online (Sandbox Code Playgroud)
现在字典的值始终是列表,您可以将第二个和后续值附加到它们而不会出现错误.
正如ecatmur指出的那样,您可以使用进一步简化(消除if
声明)d.setdefault(groupIndex, []).append(list[i])
.如果该键不存在,则该值将被视为空列表,并且您只需附加新项.你也可以用collections.defaultdict(list)
.