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.
精彩评论