在带有列表和迭代的文件中压缩行

时间:2014-06-30 20:36:32

标签: python

我想创建一个字典,其中的键是从列表keys中获取的,值是从多个文本文件中获取的行列表。让我们假设列表keys,并且要读取的所有文件具有相同的行数。

如何同时遍历列表keys和每个文件的行?我的想法是使用zip(),但这对我没用。

我知道我可以使用以下方法迭代文件中的行:

currFile = open('myfile.txt', 'r')
for line in currFile:
    # Do something

我知道我可以同时迭代两个列表:

for foo, bar in zip(foos, bars):
    # Do something

但这不起作用:

myDict = {}
keys = [17, 21, 8, 2, ..., 91]
currFile = open('myfile.txt', 'r')
for key, line in zip(keys, currFile):
    myDict[key] = line

我可以将文件中的所有行拉出到列表中,压缩它,然后运行循环,但这不会非常有效。

如何同时遍历列表keys和文件中的行,以便动态调用zip()?

5 个答案:

答案 0 :(得分:1)

  

想要创建一个字典,其中键是行号,值是从多个文本文件中获取的行列表。我们假设要读取的所有文件具有相同的行数。

此解决方案适用于任意数量的文件,此演示只有两个。演示文件file1的内容:

line0
line1
line2
line3

演示文件file2的内容:

line5
line6
line7
line8

现在列出文件对象files(例如[open('file1','r'), open('file2','r')])。

from collections import defaultdict as ddict
d = ddict(list)
for number,lines in enumerate(zip(*files)):
    for line in lines:
        d[number].append(line)

我使用Python3,如果您使用的是Python2.x,请使用izip。关闭文件:

for file in files:
    file.close()

d的内容:

defaultdict(<type 'list'>, {0: ['line0\n', 'line5\n'], 1: ['line1\n', 'line6\n'], 2: ['line2\n', 'line7\n'], 3: ['line3\n', 'line8\n']})

答案 1 :(得分:0)

def add_to_dict(someDict, filename, someNums):
    with open(filename, 'r') as f:
        for num, line in enumerate(f):
            if num in someNums:
                if num not in someDict:
                    someDict[num] = []
                someDict[num].append(line)

myDict = {}

lineNums = [2,45,13,56]

add_to_dict(myDict, "file1.txt", lineNums)
add_to_dict(myDict, "file2.txt", lineNums)

编辑:您也可以使用defaultdict(list)作为Sahand建议您不需要

if num not in someDict:
    someDict[num] = []

答案 2 :(得分:0)

使用collections.defaultdictenumerate可以使用这样的内容:

编辑:将文件名传递给函数本身可能更好:

from collections import defaultdict


def lines_to_dictionary(*files):
    result = defaultdict(list)
    for file_name in files:
        with open(file_name, 'r') as f:
            for line_number, line in enumerate(f):
                result[line_number].append(line.strip())
    return result


result = lines_to_dictionary('1.csv', '2.csv')

print result[0]  # Prints a list of first lines in all files
print result[1]  # Prints a list of second lines in all files, etc...

答案 3 :(得分:0)

使用标准dict而不是zip,一次一个文件。可以用'with'替换打开/关闭。如上所述,一次一个文件可能更适合错误处理。

d = {}
keys = set([k1, k2, ...])
files = [f1, f2, ...]
for f in files:
    ifs = open(f)
    for n, line in enumerate(ifs):
        if n in keys:
            d.setdefault(n, []).append(line)
    ifs.close()

答案 4 :(得分:0)

keys = [1, 2, 3, 4]
files = [open('a'), open('b'), open('c'), open('d')]

for x in zip(keys, *files):
    print x

编辑:您最初的想法是正确的,只是缺少扩展文件列表的语法。