有没有办法在列表中查找对象,而无需遍历列表?

问题描述:

是否有一些简单的方法来访问列表中的对象,而不使用索引或遍历列表?有没有办法在列表中查找对象,而无需遍历列表?

简而言之: 我从文本文件中读取行,分割行,并从信息创建对象。我不知道文本文件中会有什么信息。因此,例如:

roomsfile.txt

0\bedroom\A bedroom with king size bed.\A door to the east.

1\kitchen\A modern kitchen with steel and chrome.\A door to the west.

2\familyRoom\A huge family room with a tv and couch.\A door to the south.

一些Python代码:

class Rooms: 
    def __init__(self, roomNum, roomName, roomDesc, roomExits): 
     self.roomNum = roomNum 
     self.roomName = roomName 
     self.roomDesc = roomDesc 
     self.roomExits = roomExits 

    def getRoomNum(self): 
     return self.roomNum 

    def getRoomName(self): 
     return self.roomName 

    def getRoomDesc(self): 
     return self.roomDesc 

    def getRoomExits(self): 
     return self.roomExits 

def roomSetup(): 
    roomsfile = "roomsfile.txt" 
    infile = open(roomsfile, 'r') 
    rooms = [] 
    for line in infile: 
     rooms.append(makeRooms(line)) 
    infile.close() 
    return rooms 

def makeRooms(infoStr): 
    roomNum, roomName, roomDesc, roomExits = infoStr.split("\") 
    return Rooms(roomNum, roomName, roomDesc, roomExits) 

当我想知道离开卧室里有,我有过的东西,如列表迭代下面(其中“名词”由用户作为“卧室”传递):

def printRoomExits(rooms, noun): 
    numRooms = len(rooms) 
    for n in range(numRooms): 
     checkRoom = rooms[n].getRoomName() 
     if checkRoom == noun: 
      print(rooms[n].getRoomExits()) 
     else: 
      pass 

这有效,但这感觉就像我错过了一些更简单的方法...尤其是因为我有一块拼图(在这种情况下,即“卧室”)...特别是因为房间列表可能有成千上万的对象。

我可以创建一个任务:

bedroom = makeRooms(0, bedroom, etc, etc) 

然后执行:

bedroom.getRoomExits() 

但同样,我不知道会是在文本文件中的信息是什么,不知道做什么任务。 This StackOverFlow answer反对“动态创建的变量”,并赞成使用字典。我尝试了这种方法,但我找不到一种方法来访问我添加到字典中的命名对象的方法(以及信息)。

总而言之:我错过了什么愚蠢的东西?

在此先感谢!对于这本书的篇幅感到抱歉 - 我想提供足够的细节。

克里斯

+2

“...赞成使用字典我试过这种方法,但是我找不到一种方法来访问我添加到字典中的命名对象的方法(以及信息)。”以某种方式访问​​字典与访问列表相同。如果你可以做list [0] .doMethod(),你也可以做dict [“bedroom”]。doMethod()。 – Patashu

+1

如果它是一个排序列表,即您按字母顺序排列所有房间,则更容易。参见[this](http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array) – Darcys22

至少一个字典是正确的答案这里。要设置它的方式是至少索引的名字:

def roomSetup(): 
    roomsfile = "roomsfile.txt" 
    infile = open(roomsfile, 'r') 
    rooms = {} 
    for line in infile: 
     newroom = makeRooms(line) 
     rooms[newroom.roomName] = newroom 
    infile.close() 
    return rooms 

然后,给定一个名称,就可以直接访问的房间实例:

exits = rooms['bedroom'].roomExits 

是有原因的我m不使用getRoomName和getRoomExits方法 - 在Python中,getter和setter方法是不必要的。你可以直接跟踪你的实例数据,如果你以后需要改变实现,则将它们重构为属性。它为您提供了获取器和设置器的所有灵活性,而无需预先设置样板代码。

根据定义文件中的信息以及您的需求是什么,您可以获得更多信息 - 例如,我可能希望将出口信息存储在字典中,以便为每个出口映射规范名称(可能从'东','西','北'和'南'开始,并根据需要扩展为'上','下'和'dennis')到更长描述的元组以及相关的Rooms实例。

我也会将这个类命名为Room而不是Rooms,但这是一个样式问题,而不是重要的行为。

+0

Peter,Burhan和Vaughn--感谢回复!这非常有帮助。我得到了它的工作。但是我意识到我有时需要它通过索引访问信息,所以我开始搞乱OrderedDict。但是rooms.items()[n]不起作用(我得到“TypeError:'ItemsView'对象不支持索引”)。一些东西似乎已经改变,因为:http://stackoverflow.com/questions/10058140/accessing-items-in-a-ordereddict – user2454099

+0

是的,这个答案是正确的,因为写为2.7,但不是Python 3.你可以解决它通过使用'list(rooms.values())[n]',或者在创建字典后保存列表版本(例如'rooms_by_index = list(rooms.values())')并根据需要引用它。无论如何,取决于您是否在初始创建后更改房间。 –

+0

谢谢,彼得。我给列表(rooms.values())[n])一试,但得到了“TypeError:'ValuesView'对象不支持索引”错误。但我试过你的第二个建议(list(rooms.values()),而且效果很好!在dict中更新一个值也更新了列表中的对象值,这让我感到有点惊讶,但这是我想要的。帮帮我! – user2454099

您可以使用in检查成员(从字面上看,如果事情是容器)。这适用于列表,字符串和其他迭代。

>>> li = ['a','b','c'] 
>>> 'a' in li 
True 
>>> 'x' in li 
False 

你读你的房间后已经,您可以创建一个字典:

rooms = roomSetup() 

exits_of_each_room = {} 

for room in rooms: 
    exits_of_each_room[room.getRoomName()] = room.getRoomExits() 

然后你你的功能很简单:

def printRoomExits(exits_of_each_room, noun): 
    print exits_of_each_room[noun]