J'ai un exemple de fichier qui ressemble à ceci:

    @XXXXXXXXX
    VXVXVXVXVX
    +
    ZZZZZZZZZZZ
    @AAAAAA
    YBYBYBYBYBYBYB
    ZZZZZZZZZZZZ
    ...

Je souhaite lire uniquement les lignes qui tombent sur l'index 4i + 2, où je commence à 0. Je devrais donc lire la ligne VXVXV (4*0+2 = 2)... et la ligne YBYB...(4*1 +2 = 6) dans l'extrait ci-dessus. Je dois compter le nombre de 'V's, 'X's,'Y's and 'B's et le stocker dans un dict préexistant.

fp = open(fileName, "r")
lines = fp.readlines()

for i in xrange(1, len(lines),4):
    for c in str(lines(i)):
        if c == 'V':
             some_dict['V'] +=1

Quelqu'un peut-il expliquer comment éviter de sortir de l'index et lire uniquement les lignes à l'index 4 * i + 2 de la liste des lignes?

0
robinhood91 7 mars 2016 à 03:27

4 réponses

Meilleure réponse

Ne pouvez-vous pas simplement couper la liste des lignes?

lines = fp.readlines()
interesting_lines = lines[2::4]

Modifier pour d'autres en se demandant comment cela fonctionne:

La syntaxe de tranche "complète" se compose de trois parties: start:end:step

start est l'index de départ, ou 0 par défaut. Ainsi, pour un 4 * i + 2, lorsque i == 0, c'est l'indice # 2.

end est l'index de fin, ou len(sequence) par défaut. Les tranches remontent jusqu'à mais sans inclure le dernier index.

Le step est l'incrément entre les éléments choisis, 1 par défaut. Normalement, une tranche comme 3:7 retournerait les éléments 3,4,5,6 (et pas 7). Mais lorsque vous ajoutez un paramètre step, vous pouvez faire des choses comme "étape par 4".

Faire "pas à pas 4" signifie start+0, start+4, start+8, start+12, ... qui est ce que l'OP veut, tant que le paramètre start est choisi correctement.

2
aghast 7 mars 2016 à 01:59

Vous pouvez effectuer l'une des opérations suivantes:

Commencez xrange à 0 puis ajoutez 2 à i dans la boucle secondaire

for i in xrange(0, len(lines), 4):
    for c in str(lines(i+2))
        if c == 'V':
            some_dict['V'] += 1

Commencez xrange à 2, puis accédez à i comme indiqué dans votre programme d'origine

for i in xrange(2, len(lines), 4):
    for c in str(lines(i))
        if c == 'V':
            some_dict['V'] += 1
0
asdf 7 mars 2016 à 00:42

Je ne suis pas tout à fait clair sur ce que vous essayez de faire ici --- essayez-vous simplement de lire uniquement les lignes que vous voulez à partir du disque? (Dans ce cas, vous vous êtes trompé depuis le début, car readlines() lit tout le fichier.) Ou essayez-vous simplement de filtrer la liste des lignes pour sélectionner celles que vous voulez?

Je suppose que ce dernier. Dans ce cas, la chose la plus simple à faire serait d'utiliser simplement un listcomp pour filtrer la ligne par index. par exemple. quelque chose de simple comme:

indices = [x[0] * 4 + 2 for x in enumerate(lines)]
filtered_lines = [lines[i] for i in indices if len(lines) > i]

Et voilà, vous avez juste les lignes que vous voulez, pas d'erreurs d'index ou quelque chose de stupide comme ça. Ensuite, vous pouvez séparer et simplifier le reste de votre code pour effectuer le comptage, en opérant simplement sur la liste filtrée.

(juste légèrement modifié la première liste de composition pour être un peu plus idiomatique)

0
Paul Gowder 7 mars 2016 à 00:48

J'ai déjà donné une réponse similaire à une autre question: Comment puis-je faire cela dans un fichier?

Une meilleure solution (en évitant les boucles inutiles) serait

fp = open(fileName, "r")
def addToDict(letter):
    someDict[letter] += 1;

[addToDict('V') for 'V' in str(a) for a in fp.readlines()[2::4]];

J'ai essayé d'en faire une fonction anonyme sans succès, si quelqu'un pouvait le faire, ce serait excellent.

-2
Community 23 mai 2017 à 12:07