2009-11-23 10 views
3

(je travaille de manière interactive avec un objet WordprocessingDocument dans IronPython à l'aide du SDK OpenXML, mais c'est vraiment une question générale Python qui devrait être applicable dans toutes les implémentations)Créer un nouveau tuple avec un élément modifié

Je suis en train pour extraire certaines tables d'un certain nombre de documents Word. Pour chaque table, J'ai un itérateur qui me donne des objets de ligne de table. J'utilise ensuite l'instruction de générateur suivante pour obtenir un tuple de cellules de chaque ligne:

for row in rows: 
    t = tuple([c.InnerText for c in row.Descendants[TableCell]()]) 

Chaque tuple contient 4 éléments. Maintenant, dans la colonne t[1] pour chaque tuple, j'ai besoin d'appliquer une regex aux données. Je sais que les tuples sont immuables, donc je suis heureux de créer un nouveau tuple, ou de construire le tuple d'une manière différente. Etant donné que row.Descendants[TableCell]() retourne un itérateur, quelle est la façon la plus pythonique (ou au moins la plus simple) de construire un tuple à partir d'un itérateur où je veux modifier l'élément n retourné?

Ma méthode force brute est en ce moment pour créer un tuple de la tranche de gauche (t[:n-1]), les données modifiées dans t[n] et la bonne tranche (t[n+1:]), mais je me sens comme le module itertools devrait avoir quelque chose à me aider ici.

Répondre

6
def item(i, v): 
    if i != 1: return v 
    return strangestuff(v) 

for row in rows: 
    t = tuple(item(i, c.InnerText) 
      for i, c in enumerate(row.Descendants[TableCell]()) 
      ) 
+0

C'est pourquoi je devrais toujours garder une copie de "Python in a Nutshell" sur mon bureau. Je n'avais aucune idée de l'énumération intégrée, n'ayant jamais eu besoin auparavant. En attendant les réponses, j'ai concocté une construction similaire en utilisant itertools.izip et itertools.count. Merci Alex! – technomalogical

+0

@ tech & c, vous êtes les bienvenus! Oui, vous pourriez synthétiser 'enumerate' s'il n'était pas intégré, mais c'est un outil fréquemment utilisé, donc la compacité et la vitesse sont souvent particulièrement agréables à avoir ;-). –

1

Si chaque tuple contient 4 éléments, puis, franchement, je pense que vous feriez mieux de les affecter à des variables individuelles, manipuler ceux-ci, puis la construction de votre tuple:

for row in rows: 
    t1, t2, t3, t4 = tuple([c.InnerText for c in row.Descendants[TableCell]()]) 
    t1 = ... 
    t = (t1, t2, t3, t4) 
+0

Malheureusement, le nombre de colonnes que je vais utiliser varie d'une table à l'autre, donc je ne peux pas les affecter à une variable concrète. – technomalogical

2

Je voudrais faire:

temp_list = [c.InnerText for c in row.Descendants[TableCell]()] 
temp_list[2] = "Something different" 
t = tuple(temp_list) 

Il fonctionnerait comme ceci:

>>> temp_list = [i for i in range(4)] 
>>> temp_list[2] = "Something different" 
>>> t = tuple(temp_list) 
>>> t 
(0, 1, 'Something different', 3) 
0

Ce que j'ai fait en général, mais ne suis pas fan de:

l = liste (oldtuple) l [2] = toto t = tuple (l)

Je veux quelque chose de genre comme la mise à jour() pour dicts

newtuple = mise à jour (oldtuple, (None, None, val, None))

Ou peut-être la bonne structure est un zip

newtuple = mise à jour (oldtuple, ((2, val), (3, val)))