有没有办法在列表中查找对象,而无需遍历列表?
是否有一些简单的方法来访问列表中的对象,而不使用索引或遍历列表?有没有办法在列表中查找对象,而无需遍历列表?
简而言之: 我从文本文件中读取行,分割行,并从信息创建对象。我不知道文本文件中会有什么信息。因此,例如:
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反对“动态创建的变量”,并赞成使用字典。我尝试了这种方法,但我找不到一种方法来访问我添加到字典中的命名对象的方法(以及信息)。
总而言之:我错过了什么愚蠢的东西?
在此先感谢!对于这本书的篇幅感到抱歉 - 我想提供足够的细节。
克里斯
至少一个字典是正确的答案这里。要设置它的方式是至少索引的名字:
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,但这是一个样式问题,而不是重要的行为。
Peter,Burhan和Vaughn--感谢回复!这非常有帮助。我得到了它的工作。但是我意识到我有时需要它通过索引访问信息,所以我开始搞乱OrderedDict。但是rooms.items()[n]不起作用(我得到“TypeError:'ItemsView'对象不支持索引”)。一些东西似乎已经改变,因为:http://stackoverflow.com/questions/10058140/accessing-items-in-a-ordereddict – user2454099
是的,这个答案是正确的,因为写为2.7,但不是Python 3.你可以解决它通过使用'list(rooms.values())[n]',或者在创建字典后保存列表版本(例如'rooms_by_index = list(rooms.values())')并根据需要引用它。无论如何,取决于您是否在初始创建后更改房间。 –
谢谢,彼得。我给列表(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]
“...赞成使用字典我试过这种方法,但是我找不到一种方法来访问我添加到字典中的命名对象的方法(以及信息)。”以某种方式访问字典与访问列表相同。如果你可以做list [0] .doMethod(),你也可以做dict [“bedroom”]。doMethod()。 – Patashu
如果它是一个排序列表,即您按字母顺序排列所有房间,则更容易。参见[this](http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array) – Darcys22