简体   繁体   中英

How to access a specific class instance by attribute in python?

Say I have a class Box with two attributes, self.contents and self.number. I have instances of box in a list called Boxes. Is there anyway to access/modify a specific instance by its attribute rather than iterating through Boxes? For example, if I want a box with box.number = 40 (and the list is not sorted) what would be the best way to modify its contents.

If you need to do it more frequently and you have unique number s, then create a dictionary:

numberedBox = dict((b.number, b) for b in Boxes)

you can then access your boxes directly with numbers:

numberedBox[40]

but if you want to change their number, you will have to modify the numberedBox dictionary too...

Otherwise yes, you have to iterate over the list.

The most straightforward way is to use a list comprehension:

answer=[box for box in boxes if box.number==40]

Be warned though. This actually does iterate over the whole list . Since the list is not sorted, there is no faster method than to iterate over it (and thus do a linear search), unless you want to copy all the data into some other data structure (eg dict , set or sort the list ).

使用内置的过滤器:

wanted_boxes = filter(lambda box: box.number == 40, boxes)

Although not as flexible as using a dictionary, you might be able to get by using a simple lookup table to the map box numbers to a particular box in boxes . For example if you knew the box numbers could range 0...MAX_BOX_NUMBER , then the following would be very fast. It requires only one full scan of the Boxes list to setup the table.

MAX_BOX_NUMBER = ...

# setup lookup table   
box_number = [None for i in xrange(MAX_BOX_NUMBER+1)]
for i in xrange(len(Boxes)):
    box_number[Boxes[i].number] = Boxes[i]

box_number[42] # box in Boxes with given number (or None)

If the box numbers are in some other arbitrary range, some minor arithmetic would have to be applied to them before their use as indices. If the range is very large, but sparsely populated, dictionaries would be the way to go to save memory but would require more computation -- the usual trade-off.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM