【问题标题】:"for" loop not working in python 3.6“for”循环在 python 3.6 中不起作用
【发布时间】:2017-02-10 07:22:33
【问题描述】:

我一直致力于合并 3 个文本文件。

在第一个文件中,我有成对的字符串(不是 int)

在第二个文件中,我有来自文件 1 的字符串定义

在第三个中,第一个文件中的字符串还有另一个定义(也是字符串)

我的代码是:

for line1 in file1:
    wl1 = ''
    wl2 = ''
    kw1 = ''
    kw2 = ''
    dz1, dz2, none = line1.split(';')
    for line2 in file2:
        dz_wl,  wl, none = line2.split(';')
        if str(dz_wl) == str(dz1):
            wl1 = wl
        elif str(dz_wl) == str(dz2):
            wl2 = wl
        for line3 in file3:
            dz_kw, kw, none = line3.split(';')
            if str(dz_kw) == str(dz1):
                kw1 = kw
            elif str(dz_kw) == str(dz2):
                kw2 = kw
    print(dz1 + ';' + wl1 + ';' + kw1 + ';' + dz2 + ';' + wl2 + ';' + kw2 + '\n')

它似乎至少可以工作一次,因为它为第一行打印了正确的结果 结果:

1;a;123;2;b;4124

2;;;3;;

4;;;5;;

6;;;7;;

6;;;8;;

9;;;1;;

7;;;1;;

7;;;3;;

6;;;4;;

7;;;10/2;;

10/2;;;10/1;;

12;;;13;;

11;;;3;;

要改变什么,以使代码适用于每一行?

file1 包含:

1;2;

2;3;

4;5;

6;7;

6;8;

9;1;

7;1;

7;3;

6;4;

7;10/2;

10/2;10/1;

12;13;

11;3;

文件2:

1;a;

2;b;

3;c;

4;d;

5;e;

6;f;

7;g;

8;h;

9;i;

10/1;j;

10/2;k;

11;l;

12;m;

13;n;

文件3:

1;123;

2;321;

3;554;

4;3313;

5;334;

6;564;

7;3234;

8;56345;

9;2346;

10/1;342;

10/2;553;

11;23;

12;453;

13;2234;

【问题讨论】:

  • 如果不将文件对象“倒回”到file.seek(0) 的开头,您将无法多次循环文件对象。但是,您最好在循环之前将文件完全读入内存。
  • 您在这里重新发明了字符分隔文件阅读轮。使用csv 模块; reader = csv.reader(fileobj, delimiter=';') 会给你完整的解析行。 all_rows = list(reader) 会将其读入内存。
  • 你能发帖吗,你会如何更改我的代码?我对 python 还很陌生
  • 我不明白您的结果中的第一行是如何创建的。将所有文件读入一个字符串列表并使用索引为初学者提取相关数据可能是最简单的。

标签: python list python-3.x for-loop text-files


【解决方案1】:

您试图多次循环遍历一个文件对象。文件对象就像长长的磁带,读取一行或块会移动 文件指针,即下一次读取或写入的位置。读取整个文件后,该指针位于文件“磁带”的最后,并且您无法从该位置读取更多内容(那里没有更多数据),直到文件指针通过其他方式再次移动.

您要么需要在每次想要循环时打开文件对象,要么将文件指针倒回到开头。您可以使用file.seek(0) call 进行后者。

但是,一次又一次地从文件中读取是很慢的。由于您所做的只是将这些额外文件用作 maps(将一行中的一个值映射到另一个值),因此您实际上应该将它们读入内存中的字典。这样您就不必完全循环,并且在此过程中使您的代码变得非常、非常快。

你也应该使用csv module,而不是自己分裂。该模块在引号和其他极端情况下更有效地处理读取和拆分:

import csv
import sys

with open(filename2, 'r', newline='') as file2:
    reader = csv.reader(file2, delimiter=';')
    file2_map = dict(row[:2] for row in reader)

with open(filename3, 'r', newline='') as file3:
    reader = csv.reader(file3, delimiter=';')
    file3_map = dict(row[:2] for row in reader)

with open(filename1, 'r', newline='') as file1:
    reader = csv.reader(file1, delimiter=';')
    writer = csv.writer(sys.stdout, delimiter=';')
    for dz1, dz2, *remainder in reader:
        wl1 = file2_map.get(dz1, '')
        wl2 = file2_map.get(dz2, '')
        kw1 = file3_map.get(dz1, '')
        kw2 = file3_map.get(dz2, '')
        writer.writerow([dz1, dz2, wl1, wl2, kw1, kw2])

由于您还要写出分号分隔的信息,因此您可以使用相同的csv 模块生成csv.writer() 对象以再次写出数据。在上面的例子中,我写信给sys.stdout,但你可以写任何你喜欢的文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    相关资源
    最近更新 更多