Python - 从另一个文件写入新文件

时间:2014-07-11 14:26:52

标签: python file function input

我希望必须将第一个字段(用户名)从File1和第二个字段(密码)输出到第三个文件,该文件在函数期间创建但我无法执行。 :(

文件的格式始终相同:

文件1:

Username:DOB:Firstname:Lastname:::

文件2:

Lastname:Password

我目前的代码:

def merge(f1,f2,f3):
   with open(f3, "a") as outputFile:
      with open(f1) as usernameFile:
         for line in usernameFile:
            line = line[:-3]
            username = line.split(':')
            outputFile.write(username[0])
      with open(f2) as passwordFile:
         for line in passwordFile:
            password = line.split(':')
            outputFile.write(password[1])

merge('file1.txt', 'file2.txt', 'output.txt')

我希望File1的用户名和File2的密码用布局写入File3:

Username:Password
Username:Password
Username:Password

任何帮助将不胜感激。 :)

6 个答案:

答案 0 :(得分:2)

如果文件的排序相同(即用户在两个文件中的顺序相同),请使用tip in this answer同时迭代这两个文件,而不是在示例中依次迭代。< / p>

from itertools import izip

with open(f3, "a") as outputFile:
  for line_from_f1, line_from_f2 in izip(open(f1), open(f2)):
    username = line_from_f1.split(':')[0]
    password = line_from_f1.split(':')[1]
    outputfile.write("%s:%s" % (username, password))

如果文件的排序方式不同,请先从lastname创建一个包含密钥username和值file1的字典。然后使用lastname中的键password和值file2创建第二个字典。然后迭代任一dict的键并打印两个值。

答案 1 :(得分:1)

摘要从文件i / o中提取数据,然后您可以使用不同的提取函数重用merge()

import itertools as it
from operator import itemgetter    
from contextlib import contextmanager

def extract(foo):
    """Extract username and password, compose and return output string

    foo is a tuple or list
    returns str

    >>> len(foo) == 2
    True
    """
    username = itemgetter(0)
    password = itemgetter(1)
    formatstring = '{}:{}\n'
    item1, item2 = foo
    item1 = item1.strip().split(':')
    item2 = item2.strip().split(':')
    return formatstring.format(username(item1), password(item2))

@contextmanager
def files_iterator(files):
    """Yields an iterator that produces lines synchronously from each file

    Intended to be used with contextlib.contextmanager decorator.
    yields an itertools.izip object

    files is a list or tuple of file paths - str
    """
    files = map(open, files)
    try:
        yield it.izip(*files)
    finally:
        for file in files:
            file.close()


def merge(in_files,out_file, extract):
    """Create a new file with data extracted from multiple files.

    Data is extracted from the same/equivalent line of each file:
        i.e. File1Line1, File2Line1, File3Line1
             File1Line2, File2Line2, File3Line2

    in_files --> list or tuple of str, file paths
    out_file --> str, filepath
    extract --> function that returns list or tuple of extracted data

    returns none
    """
    with files_iterator(in_files) as files, open(out_file, 'w') as out:
        out.writelines(map(extract, files))
##        out.writelines(extract(lines) for lines in files)

merge(['file1.txt', 'file2.txt'], 'file3.txt', extract)

Files_IteratorWith Statement Context Manager,允许多个同步文件迭代,并确保文件将被关闭。这是阅读的良好开端 - Understanding Python's "with" statement

答案 2 :(得分:1)

这是您需要对代码进行的最小更改才能使其正常工作:

def merge(f1,f2,f3):
  with open(f3, "a") as outputFile:

     with open(f1) as usernameFile:
        for line in usernameFile:
           username = line.split(':')[0]
           lastname = line.split(':')[3]
           outputFile.write(username)

        with open(f2) as passwordFile: 
           for line in passwordFile:
              lN, password = line.split(':')
              if lN == lastname: outputFile.write(password[1]) 

merge('file1.txt', 'file2.txt', 'output.txt')

但是,这种方法并不是很好,因为它多次读取文件。我会继续为第二个文件创建一个字典,并以lastname作为键。字典在这些情况下非常有用。可以按照以下方式制作字典:

def makeDict(f2):
  dOut = {}
  with open(f2) as f:
     for l in f:
        dOut[ l.split(':')[0] ] = l.split(':')[1]

  return dOut


def merge(f1,f2,f3):

  pwd = makeDict(f2)
  print pwd
  with open(f3, "a") as outputFile:

     with open(f1) as usernameFile:
        for line in usernameFile:
           if line.strip() == '': continue
           username = line.split(':')[0]
           lastname = line.split(':')[3]
           if lastname in pwd: 
              outputFile.write(username + ':' + pwd[lastname] + '\n')


merge('f1.txt', 'f2.txt', 'f3.txt'  )

我刚使用这些文件运行以下程序:

f1.txt

Username0:DOB:Firstname:Lastname0:::
Username1:DOB:Firstname:Lastname1:::
Username2:DOB:Firstname:Lastname2:::
Username3:DOB:Firstname:Lastname3:::

f2.txt

Lastname0:Password0
Lastname1:Password1
Lastname2:Password2
Lastname3:Password3

得到了输出:

Username0:Password0

Username1:Password1

Username2:Password2

Username3:Password3

我确实添加了最后一行merge(...)和另一行用于跳过输入文本中的空白行,但除此之外,一切都应该没问题。如果merge(...函数未被调用,则不会有任何输出。

答案 3 :(得分:0)

我建议构建两个词典来表示每个文件中的数据,然后根据该结构编写File3:

d1 = {}
with open("File1.txt", 'r') as f:
    for line in f:
        d1[line.split(':')[3]] = line.split(':')[0]

d2 = {}
with open("File2.txt", 'r') as f:
    for line in f:
        d2[line.split(':')[0]] = line.split(':')[1]

这将为您提供两个类似的词典:

d1 = {Lastname: Username}
d2 = {Lastname: Password}

然后将其写入文件3,只需运行dicitonary:

的键
with open("File3.txt", 'w') as f:
    for key in d1:
        f.write("{}:{}\n".format(d1[key], d2[key]))

需要注意的一些事项:

  • 如果这些文件没有相同的值,那么您需要为此进行一些处理(如果是这种情况请告诉我,我可以提出一些想法)方式

  • 此方法不保留文件在

  • 中的任何顺序
  • 代码假定所有行的格式相同。一个更复杂的文件将需要一些代码来处理&#34; odd&#34;线

答案 4 :(得分:0)

如果你在每个文件中有相同排序的行,那么可以避免这种情况。但是,如果它变得更复杂,那么你应该使用pandas。使用pandas,您基本上可以进行连接,因此,无论每个文件中的行如何排序,这都可以。它也非常简洁。

import pandas as pd

df1 = pd.read_csv(f1, sep=':', header=None).ix[:,[0,3]]
df1.columns = ['username', 'lastname']
df2 = pd.read_csv(f2, sep=':', header=None)
df2.columns = ['lastname', 'password']
df3 = pd.merge(df1, df2).ix[:,['username','password']]
df3.to_csv(f3, header=False, index=False, sep=':')

请注意,您还可以选择执行外连接。如果由于某种原因,文件中存在没有密码的用户名,反之亦然,这很有用。

答案 5 :(得分:0)

这非常接近。确保输入文件末尾没有空白行,或者在阅读时添加代码以跳过空白行。

#!/usr/bin/env python
"""
File 1:
Username:DOB:Firstname:Lastname:::

File2:
Lastname:Password

File3:
Username:Password

"""

def merge(f1,f2,f3):
   username_lastname = {}
   with open(f3, "a") as outputFile:
      with open(f1) as usernameFile:
         for line in usernameFile:
            user = line.strip().split(':')
            print user
            username_lastname[user[3]] = user[0] # dict with Lastname as key, Username as value

      print username_lastname      
      with open(f2) as passwordFile:
         for line in passwordFile:
            lastname_password = line.strip().split(':')
            print lastname_password
            password = lastname_password[1]
            username = username_lastname[lastname_password[0]]
            print username, password
            out_line = "%s:%s\n" % (username, password)
            outputFile.write(out_line)
         outputFile.close()

merge('f1.txt', 'f2.txt', 'output.txt')

f1:
Username1:DOB:Firstname:Lastname1:::
Username2:DOB:Firstname:Lastname2:::
Username3:DOB:Firstname:Lastname3:::

f2:
Lastname1:Password1
Lastname2:Password2
Lastname3:Password3

f3: 
Username1:Password1
Username2:Password2
Username3:Password3