【问题标题】:Python for loop iteration to merge multiple lines in a single linePython for循环迭代将多行合并到一行中
【发布时间】:2014-02-04 10:00:13
【问题描述】:

我有一个我正在尝试解析的 CSV 文件,但问题是其中一个单元格包含充满空值和换行符的数据块。我需要将每一行包含在一个数组中,并将该特定单元格中的所有内容合并到相应的行中。我最近发布了一个类似的问题,答案部分解决了我的问题,但是我在构建一个循环遍历不满足特定启动条件的每一行时遇到了问题。我的代码只合并了不满足该条件的第一行,但之后就中断了。

我有:

file ="myfile.csv"
condition = "DAT"

data = open(file).read().split("\n")
for i, line in enumerate(data):
    if not line.startswith(condition):
        data[i-1] = data[i-1]+line
        data.pop(i)
print data

对于如下所示的 CSV:

Case  | Info
-------------------
DAT1    single line  
DAT2    "Berns, 17, died Friday of complications from Hutchinson-Gilford progeria   syndrome, commonly known as progeria. He was diagnosed with progeria when he was 22 months old. His physician parents founded the nonprofit Progeria Research Foundation after his diagnosis.

Berns became the subject of an HBO documentary, ""Life According to Sam."" The exposure has brought greater recognition to the condition, which causes musculoskeletal degeneration, cardiovascular problems and other symptoms associated with aging.

Kraft met the young sports fan and attended the HBO premiere of the documentary in New    York in October. Kraft made a $500,000 matching pledge to the foundation.

The Boston Globe reported that Berns was invited to a Patriots practice that month, and gave the players an impromptu motivational speech.

DAT3    single line
DAT4    YWYWQIDOWCOOXXOXOOOOOOOOOOO 

它确实将完整的句子与上一行连接起来。但是当它遇到双空格或双行时,它会失败并将其注册为新行。例如,如果我打印:

data[0]

输出是:

DAT1    single line

如果我打印:

data[1]

输出是:

DAT2    "Berns, 17, died Friday of complications from Hutchinson-Gilford progeria syndrome, commonly known as progeria. He was diagnosed with progeria when he was 22 months old. His physician parents founded the nonprofit Progeria Research Foundation after his diagnosis.

但是如果我打印:

data[2]

输出是:

Berns became the subject of an HBO documentary, ""Life According to Sam."" The exposure has brought greater recognition to the condition, which causes musculoskeletal degeneration, cardiovascular problems and other symptoms associated with aging.

代替:

DAT3    single line

如何合并“信息”列上的全部文本,使其始终与相应的 DAT 行匹配,而不是作为新行弹出,而不管空字符还是换行符?

【问题讨论】:

  • 您在迭代数据时使用pop。你不应该改变你正在迭代的东西。将您想要的数据复制到新列表中。
  • 为什么不使用 cvs 模块? docs.python.org/2/library/csv.html 它能够处理各种分隔符和转义字符 在您的情况下可能是 delimiter="\t" 。

标签: python parsing loops csv merge


【解决方案1】:

在迭代 data 时更改它是“不好的”

new_data = []
for line in data:
    if not new_data or line.startswith(condition):
        new_data.append(line)
    else:
        new_data[-1] += line
print new_data

【讨论】:

  • 这适用于演示 CSV。但是,对于实际数据,它会为包含以下内容的行抛出“IndexError:list index out of range”:main_records[i-1] += line
  • nvm...我意识到这是标题行,什么都搞砸了。如果从 CSV 中删除,它可以工作。那将是另一个问题。谢谢!
  • 已编辑以考虑第一行是否失败的情况
  • 奇怪...在多行的单元格中以某种方式切断了开头,就像给我“伯恩斯成为 HBO 纪录片的主题...”而不是“DAT2”伯恩斯,17 ,星期五死于哈钦森-吉尔福德早衰综合症的并发症,通常称为早衰。他在 22 个月大时被诊断出患有早衰症。他的医生父母在他确诊后成立了非营利性早衰研究基金会。 Berns 成为 HBO 纪录片的主题......”正在合并到前一行,但切断了之前的所有内容。
  • 有帮助,但仍然有这个问题......我认为正则表达式正在解决它
【解决方案2】:

你可以用正则表达式直接将行拆分成data:

Python

import re

f = open("myfile.csv")
text = f.read()
data = re.findall("\n(DAT\d+.*)", text)

如果没有帮助,请纠正我。

更新:

我相信,这将解决新行的问题:

import re

f = open("myfile.csv")
text = f.read()
lines = re.split(r"\n(?=DAT\d+)", text)
lines.pop(0)

【讨论】:

  • 好的,这个不包括换行后的其余内容。它在单元格内的第一个新行之后中断,并且不包含单元格的其余部分或下一个单元格。我得到了类似的输出,例如“if line.startswith(condition): new_data.append(line)”
  • 你说得对,我应该使用re.split。我的答案有更新:)
  • 哇,迈赫迪,就是这样! ...有一件事,我怎样才能将正则表达式限制为完全“DAT”,因为如果我使用 DAT0001,DAT0002 它可以工作,但如果有字符而不是数字,那么它不会,例如,DAT0001 和 DAT0002 将打印为单独的行,但 DAT000 和 DATNEXT 将合并在一起。
  • DAT\d+ 匹配所有后跟数字的“DAT”。如果您希望它与以 DAT 开头的任何单词匹配,请将 \d 替换为 .\n(?=DAT.+)
  • 嗯,学习正则表达式不光是看书。首先你应该了解一些基础知识,比如你可以用正则表达式做什么和不能做什么,然后你应该在编程中练习它。希望此链接对您有所帮助:stackoverflow.com/questions/4736/learning-regular-expressions
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 2018-08-16
  • 1970-01-01
  • 2020-07-17
  • 2020-07-30
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
相关资源
最近更新 更多