开发者

Overloading List Comprehension Behavior?

I'm tasked with creating a model of a cage of hardware. Each cage contains N slots, each slot may or may not contain a card.

I would like to model the cage using a list. Each list index would correspond to the slot number. cards[0].name="Card 0", etc.

This would allow my users to query the model via simple list comprehensions. For example:

for card in cards:
    print card.name

My users, which are not sophisticated Python users, will be interacting with the model in real-time, so it is not practical to have the list index not correspond to a populated card. In other words, if the user removes a card, I need to do something that will indicate that the card is not populated—my first impulse was to set the list item to None.

The Bossman likes this scheme, but he's not crazy about the list comprehension above failing if there is a card missing. (Which it currently does.) He's even less supportive of requiring the users to learn enough Python to create list comprehension expressions that will ignore None.

My thought was to sub-class the list class, to create a newclass. It would work exactly like a list, except for card in cards would only return members not set to None.

Will someone please demonstrate how t开发者_Go百科o overload the list class so that list comprehensions called on the subclass will ignore None? (My Python skills have so far begun to break down when I attempt this.)

Can anyone suggest a better approach?


>>> class MyList(list):
...     def __iter__(self):
...         return (x for x in list.__iter__(self) if x is not None)
... 
>>> 
>>> ml = MyList(["cat", "dog", None, "fox"])
>>> for item in ml:
...     print item
... 
cat
dog
fox

>>> [x for x in ml]
['cat', 'dog', 'fox']
>>> list(ml)
['cat', 'dog', 'fox']


You could provide a generator/iterator for this.

def installed(cage):
    for card in cage:
        if card:
            yield card

cards = ["Adaptec RAID", "Intel RAID", None, "Illudium Q-36 Explosive Space Modulator"]

# print list of cards
for card in installed(cards):
    print card


You can do something like this to get the names if you're using 2.6 or newer:

names = [x.name for x in cards if x is not None]

That should get close to what you're after I think.


Perhaps define a function (assuming cards is a global variable?!?):

def pcards():
    for card in cards:
        if card:
            print card.name

so your users can simply type pcards() to get a listing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜