2009-04-13 4 views
2

Je veux un programme Python pour importer une liste de mots à partir d'un fichier texte et imprimer le contenu du fichier texte en deux listes. Les données contenues dans le fichier texte est sur ce formulaire:Quelque chose ne va pas avec la sortie de la liste en Python

A Alfa 
B Betta 
C Charlie 

Je veux un programme Python pour imprimer une liste avec A, B, C et une avec Alfa, Betta, Charlie.

C'est ce que j'ai écrit:

english2german = open('english2german.txt', 'r') 
englist = [] 
gerlist = [] 

for i, line in enumerate(english2german): 
    englist[i:], gerlist[i:] = line.split() 

Ce fait deux listes, mais imprime uniquement la première lettre de chaque mot. Comment puis-je faire mon code pour imprimer le mot entier?

Répondre

6

Vous voulez quelque chose comme ceci:

english2german = open("english2german.txt") 
englist = [] 
gerlist = [] 

for line in english2german: 
    (e, g) = line.split() 
    englist.append(e) 
    gerlist.append(g) 

Le problème avec votre code est avant que englist[i:] est en fait une tranche d'une liste, non seulement un seul indice. Une chaîne est également itérable, donc vous étiez en train de bourrer une seule lettre dans plusieurs index. En d'autres termes, quelque chose comme gerlist[0:] = "alfa" aboutit effectivement à gerlist = ['a', 'l', 'f', 'a'].

+0

+1 pour une meilleure lisibilité. – tgray

1

Comme cela, vous dire:

english2german = open('k.txt', 'r') 
englist = [] 
gerlist = [] 

for i, line in enumerate(english2german): 
    englist.append(line.split()[0]) 
    gerlist.append(line.split()[1]) 

print englist 
print gerlist 

qui génère:

[ 'A', 'B', 'C'] [ 'Alfa', 'Betta', 'Charlie']

6

et même plus courte que amo-ej1's answer, et probablement plus rapide:

In [1]: english2german = open('english2german.txt') 
In [2]: eng, ger = zip(*(line.split() for line in english2german)) 
In [3]: eng 
Out[3]: ('A', 'B', 'C') 
In [4]: ger 
Out[4]: ('Alfa', 'Betta', 'Charlie') 

Si vous utilisez Python 3.0 ou from future_builtins import zip, c'est aussi efficace en mémoire. Sinon, remplacez zip par izip de itertools si english2german est très long.

+0

C'est ... horrible. C'est peut-être plus rapide, mais je doute vraiment que ce soit "utilement plus rapide", et c'est beaucoup plus difficile à lire (le * surtout) – dbr

+0

c'est l'opération 'unzip', c'est un idiome assez courant pour joindre des paires de choses. – Autoplectic

+0

J'ai comparé la méthode zip au code dans la réponse de mipadi. zip est légèrement plus lent avec un petit ensemble de données, mais légèrement plus rapide avec 10.000 lignes ... mais la différence est d'environ 0.05 sur chaque .. – dbr

1

Les solutions déjà affichées sont OK si vous n'avez aucun espace dans l'un des mots (c'est-à-dire que chaque ligne a un seul espace). Si je comprends bien, vous essayez de construire un dictionnaire, donc je vous suggère de considérer le fait que vous pouvez aussi avoir des définitions d'expressions de mots multiples. Dans ce cas, vous feriez mieux d'utiliser un autre caractère au lieu d'un espace pour séparer la définition du mot. Quelque chose comme "|", qui est impossible à apparaître dans un mot.

Ensuite, vous faites quelque chose comme ceci:

for line in english2german: 
    (e, g) = line.split("|") 
    englist.append(e) 
    gerlist.append(g) 
+0

-1: changer le format de fichier. Utilisez la partition au lieu de split - même effet - pas de changement au format de fichier. –

+0

Eh bien, je n'ai pas dit qu'il devait * changer * le format de fichier! Je viens * suggéré *. Je ne vois pas vraiment comment la partition peut résoudre le problème que j'ai décrit, de toute façon. – ibz

3

juste un ajout: vous travaillez avec des fichiers. s'il vous plaît les fermer :) ou utilisez la construction avec:

with open('english2german.txt') as english2german: 
    englist, gerlist = zip(*(line.split() for line in english2german)) 
1

légèrement méta-réponse (?) À Autoplectic's suggestion d'utiliser zip()

Avec 3 lignes dans le fichier d'entrée (à partir des données fournies dans la question):

Le procédé zip() prend une moyenne de 0.404729390144 secondes, par rapport à 0.341339087486 avec la simple boucle for la construction de deux listes (le code de mipadi's actuellement la réponse acceptée).

Avec 10.000 lignes dans le fichier d'entrée (. Aléatoire généré 3-12 mots de caractères I réduit la timeit.repeat() valeurs 100 fois, répété deux fois):

zip() pris une moyenne de 1.43965339661 secondes, par rapport à 1.52318406105 avec le pour la boucle.

Les deux benchmarks ont été réalisés en utilisant la version Python 2.5.1

A peine une énorme différence .. Compte tenu de la façon beaucoup plus lisible la simple boucle est, je vous conseille de l'utiliser .. Le code zip pourrait être un peu plus rapide avec de gros fichiers, mais la différence est d'environ 0,083 secondes avec 10.000 lignes ..

Code Benchmarking:

import timeit 

# https://stackoverflow.com/questions/743248/something-wrong-with-output-from-list-in-python/743313#743313 
code_zip = """english2german = open('english2german.txt') 
eng, ger = zip(*(line.split() for line in english2german)) 
""" 

# https://stackoverflow.com/questions/743248/something-wrong-with-output-from-list-in-python/743268#743268 
code_for = """english2german = open("english2german.txt") 
englist = [] 
gerlist = [] 

for line in english2german: 
    (e, g) = line.split() 
    englist.append(e) 
    gerlist.append(g) 
""" 

for code in [code_zip, code_for]: 
    t = timeit.Timer(stmt = code) 
    try: 
     times = t.repeat(10, 10000) 
    except: 
     t.print_exc() 
    else: 
     print "Code:" 
     print code 
     print "Time:" 
     print times 
     print "Average:" 
     print sum(times)/len(times) 
     print "-" * 20 
Questions connexes