2010-03-24 5 views
2

J'ai un problème mineur lors de la vérification des éléments dans une liste: J'ai deux fichiers avec le contenu quelque chose comme çacontenu fusion de deux listes basées sur une si boucle

file 1:  file2: 
47   358 47 
48   450 49 
49   56 50 

J'analysé les deux fichiers en deux listes et utilisé le code suivant pour vérifier

for i in file_1: 
    for j in file_2: 
     j = j.split() 
     if i == j[1]: 
     x=' '.join(j) 
     print >> write_in, x 

Je suis maintenant essayer d'obtenir un « 0 » si la valeur de file_1 n'est pas là dans file_2 par exemple, la valeur « 48 » est pas il y a file_2 donc j'ai besoin pour obtenir la sortie comme (avec un seul espace entre les deux numéros) conditions e doivent produire un seul fichier de sortie:

output_file: 
    358 47 
    0 48 
    450 49 
    56 50 

J'ai essayé d'utiliser l'approche dictionnaire, mais je ne comprends pas bien ce que je voulais (en fait je ne sais pas comment utiliser le dictionnaire correctement en python;)). Toute aide sera appréciée.

+0

ce n'est pas un python valide – SilentGhost

+0

Avez-vous essayé de conserver else? else x = '0'.join (j) –

+0

Les numéros (dans le fichier 1 et le deuxième numéro dans le fichier 2) sont-ils toujours dans l'ordre? Ordre alphabétique ou numérique? Sont-ils même toujours des numéros? Le fichier de sortie doit-il être en ordre? –

Répondre

1

Vous pouvez modifier votre code assez facilement:

for i in file_1: 
    x = None 
    for j in file_2: 
     j = j.split() 
     if i == j[1]: 
      x = ' '.join(j) 
    if x is None: 
     x = ' '.join(['0', i]) 

En fonction de vos entrées, toute la tâche pourrait être bien sûr simplifiée encore plus loin. À l'heure actuelle, votre code est 0(n**2) complexité.

+1

En fait, c'est O (N + M). Vous avez juste besoin d'un balayage séquentiel de chaque fichier. – tzot

2
r1=open('file1').read().split() 
r2=open('file2').read().split() 

d=dict(zip(r2[1::2],r2[::2])) 

output='\n'.join(x in d and d[x]+' '+x or '0 '+x for x in r1) 

open('output_file','wb').write(output) 

test

>>> file1='47\n48\n49\n50' 
>>> file2='358 47\n450 49\n56 50' 
>>> 
>>> r1=file1.split() 
>>> r2=file2.split() 
>>> 
>>> d=dict(zip(r2[1::2],r2[::2])) # 
>>> d 
{'47': '358', '50': '56', '49': '450'} 
>>> 
>>> print '\n'.join(x in d and d[x]+' '+x or '0 '+x for x in r1) 
358 47 
0 48 
450 49 
56 50 
>>> 
+0

+1 pour être pythonique :) – anijhaw

+1

Les objets fichiers ne possèdent pas de méthode split(). open ('file1'). read(). split() peut-être? –

+0

@Daniel, Merci, j'ai juste raté pour taper .read() – YOU

1

est ici une solution lisible à l'aide d'un dictionnaire:

d = {} 
for k in file1: 
    d[k] = 0 
for line in file2: 
    v, k = line.split() 
    d[k] = v 
for k in sorted(d): 
    print d[k], k 
+0

initialiser dict à certaines valeurs est mieux fait avec '.classkeeth de fromkeys. – SilentGhost

0

Vous pouvez essayer quelque chose comme:

l1 = open('file1').read().split() 
l2 = [line.split() for line in open('file2')] 

for x, y in zip(l1, l2): 
    if x not in y: 
     print 0, x 
    print ' '.join(y) 

mais si vous suivez votre logique, la sortie doit être

358 47 
0 48 
450 49 
0 49 
56 50 

et non

358 47 
0 48 
450 49 
56 50 
0
def file_process(filename1, filename2): 

    # read first file with zeroes as values 
    with open(filename1) as fp: 
     adict= dict((line.rstrip(), 0) for line in fp) 

    # read second file as "value key" 
    with open(filename2) as fp: 
     adict.update(
      line.rstrip().partition(" ")[2::-2] # tricky, read notes 
      for line in fp) 
    for key in sorted(adict): 
     yield adict[key], key 

fp= open("output_file", "w") 
fp.writelines("%s %s\n" % items for items in file_process("file1", "file2")) 
fp.close() 

str.partition (» «) retourne un tuple de (pré-espace, l'espace, après l'espace). En découpant le tuple, en commençant à l'item 2 (post-espace) et en passant par un pas de -2, on retourne un tuple de (post-espace, pré-espace), qui sont (clé, valeur) pour le dictionnaire qui décrit la solution.

PS Um :) Je viens de remarquer que ma réponse est essentiellement la même que celle de Daniel Stutzbach.