【问题标题】:Is there a way to find objects in a list without iterating through the list?有没有办法在不遍历列表的情况下在列表中查找对象?
【发布时间】:2013-05-31 15:57:18
【问题描述】:

是否有一些简单的方法可以访问列表中的对象,而无需使用索引或遍历列表?

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

roomsfile.txt

0\卧室\一间带特大号床的卧室。\一扇通往东边的门。

1\厨房\现代化的钢制和镀铬厨房。\一扇通往西边的门。

2\familyRoom\一个带电视和沙发的巨大家庭房。\朝南的一扇门。

一些 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 反对“动态创建的变量”,并赞成使用字典。我尝试了这种方法,但我找不到一种方法来访问我添加到字典中的命名对象的方法(以及信息)。

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

提前致谢!很抱歉这篇文章太长了——我想提供足够的细节。

克里斯

【问题讨论】:

  • "...赞成使用字典。我尝试了这种方法,但我找不到访问我添加到字典中的命名对象的方法(以及信息)的方法。”在某种程度上,访问字典与访问列表相同。如果可以做list[0].doMethod(),也可以做dict["bedroom"].doMethod()。
  • 如果它是一个排序列表,也就是说,所有房间都按字母顺序排列,那就更容易了。见this

标签: python object


【解决方案1】:

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

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

然后,给定一个名称,您可以直接访问 Rooms 实例:

exits = rooms['bedroom'].roomExits

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

根据您的定义文件中存在的信息以及您的需求,您可以变得更有趣 - 例如,我可能希望将我的出口信息存储在字典中,为每个出口映射一个规范名称(可能开始'east', 'west', 'north' and 'south', 并根据需要扩展到 'up', 'down' 和 'dennis')到一个更长描述的元组和相关的 Rooms 实例。

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

【讨论】:

  • Peter、Burhan 和 Vaughn - 感谢您的回复!这很有帮助。我让它工作了。但我意识到有时我需要它来按索引访问信息,所以我开始搞乱 OrderedDict。但是 rooms.items()[n] 不起作用(我得到“TypeError:'ItemsView'对象不支持索引”)。自那以后似乎发生了一些变化:stackoverflow.com/questions/10058140/…
  • 是的,这个答案是为 2.7 编写的,但不是为 Python 3 编写的。您可以使用 list(rooms.values())[n] 解决它,或者在创建字典后保存列表版本(例如 @987654326 @) 并根据需要引用它。无论如何,这取决于您是否在最初创建房间后更改房间。
  • 谢谢,彼得。我尝试了 list(rooms.values())[n]),但得到了“TypeError:'ValuesView'对象不支持索引”错误。但是我尝试了您的第二个建议 (list(rooms.values()),效果很好!更新 dict 中的值也更新了列表中的 objects 值,这让我有点惊讶,但这正是我想要的。感谢所有帮助!
【解决方案2】:

读完房间后,您可以创建字典:

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]

【讨论】:

    【解决方案3】:

    您可以使用in 来检查成员资格(字面意思是,如果某物在 容器中)。这适用于列表、字符串和其他可迭代对象。

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

    【讨论】:

      猜你喜欢
      • 2022-08-17
      • 1970-01-01
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      • 1970-01-01
      • 2020-08-25
      相关资源
      最近更新 更多