2010-08-25 6 views
1

Je suis chargé de créer un modèle de cage de matériel. Chaque cage contient N emplacements, chaque emplacement peut contenir ou non une carte. Je voudrais modéliser la cage à l'aide d'une liste.Comportement de compréhension de liste de surcharge?

Chaque index de liste correspondrait au numéro d'emplacement. cards[0].name="Card 0", etc.

Cela permettrait à mes utilisateurs d'interroger le modèle via de simples listes de compréhension. Par exemple:

for card in cards: 
    print card.name 

Mes utilisateurs, qui ne sont pas sophistiqués utilisateurs de Python, interagiront avec le modèle en temps réel, il est donc pas pratique d'avoir l'index de la liste correspondent pas à une carte peuplée. En d'autres termes, si l'utilisateur enlève une carte, je dois faire quelque chose qui indiquera que la carte n'est pas remplie — ma première impulsion était de mettre l'élément de la liste à None. Le Bossman aime ce schéma, mais il n'est pas fou de la compréhension de la liste ci-dessus échouant s'il y a une carte manquante. (Ce qu'il fait actuellement.) Il est encore moins favorable à ce que les utilisateurs aient besoin d'apprendre suffisamment de Python pour créer des expressions de compréhension de liste qui ignoreront None.

Ma pensée était de sous-classer la classe list, pour créer un newclass. Cela fonctionnerait exactement comme une liste, sauf que for card in cards ne retournerait que les membres non définis à None.

Quelqu'un va-t-il montrer comment surcharger la classe de liste afin que les compréhensions de liste appelées dans la sous-classe ignorent None? (Mes compétences en Python ont déjà commencé à s'effondrer quand j'essaye cela.)

Quelqu'un peut-il suggérer une meilleure approche?

+0

Pouvez-vous décrire vos 'cartes'? Sont-ils des dictionnaires? Instances de classe? –

Répondre

8
>>> 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'] 
+0

D'oh! J'étais * si * proche ... la seule différence entre la mienne et la tienne est que la tienne ... fonctionne. ;-) Et ça marche bien! Bon travail! Merci! –

+0

@JS, vous êtes les bienvenus –

+0

Vous avez oublié 'super()'. – habnabit

1

Vous pouvez faire quelque chose comme ça pour obtenir les noms si vous utilisez 2.6 ou plus récent:

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

Cela devrait se rapprocher de ce que vous êtes après que je pense.

0

Peut-être définir une fonction (en supposant des cartes est une variable globale?!?):

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

afin que vos utilisateurs peuvent simplement taper pcards() pour obtenir une liste.

2

Vous pouvez fournir un générateur/itérateur pour cela.

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 
+0

+1 pour l'utilisation de "Illudium Q-36 Explosive Space Modulator" :-) –

+0

Je pense que votre code pour imprimer la liste numérotée est cassé. Il montre le Q-36 dans l'emplacement 2 –

+0

Tout à fait raison, il n'y a aucun moyen de le faire avec ce que j'ai donné, alors je l'ai enlevé. Vous auriez besoin d'une fonction d'énumération de remplacement. Ce que je vais laisser comme un exercice pour le lecteur. :-) – kindall

Questions connexes