【问题标题】:python apply different loops to different parts of the same csv filepython对同一个csv文件的不同部分应用不同的循环
【发布时间】:2022-01-09 09:28:41
【问题描述】:

我是 python 新手。我正在尝试读取一个 csv 文件,并使用它的信息来创建 2 种不同类型的对象 - “水果”和“蔬菜”。 csv文件的大体结构如下:

FRUIT
banana, yellow, sweet
orange, orange, sour
VEGETABLE
cabbage, green
spinach, green

“水果”和“蔬菜”是标题行。如您所见,“水果”对象有 3 个实例属性,而“蔬菜”有 2 个。要将正确的对象构造函数应用于正确的行,我需要区分包含“水果”和“蔬菜”的行。目前,我通过根据每行中具有值的单元格的数量进行解析。

from Fruit import *
from Vegetable import *                     # Fruit & Vegetable are Class


def build_object(filename):
    fruit_list = []
    veggie_list = []

    with open(filename, 'r') as infile:
        reader = csv.reader(infile)
        for row in reader:
            if len(row) == 3:               # corresponds with FRUIT rows
                f = Fruit(row[0], row[1], row[2])
                fruit_list.append(f)
            elif len(row) == 2:             # corresponds with VEGETABLE rows
                v = Vegetable(row[0], row[1])
                veggie_list.append(v)
    
    return 
        print(fruit_list)
        print(veggie_list)

虽然此代码似乎可以帮助我实现此 csv 文件所需的内容,但如果“卷心菜”行还包含 3 个具有值的单元格,则它没有用处。示例 csv 文件:

FRUIT
banana, yellow, sweet
orange, orange, sour
VEGETABLE
no stock, cabbage, green
spinach, green

对于这个示例 csv 文件,包含卷心菜的行有 3 个单元格,使用我上面的代码将被视为“水果”。额外的“无库存”不是属性,而是要应用不同代码的标志。

我的问题是,有没有办法创建一个 forwhile 循环来检测 csv 文件中的“FRUIT”标题行,让我可以转换之后的每一行到一个“水果”对象,然后检测“蔬菜”标题行,从哪一点我可以将后续行转换为“蔬菜”对象?提前谢谢你。

【问题讨论】:

  • 只有一个单词的行总是标题吗?如果是这样,请使用相同的行长逻辑来检测您所在的“部分”,然后写入该部分直到出现下一个标题。
  • 您是创建 CSV 的人还是来自其他地方的数据?理想情况下,您的 CSV 应该有一个标题行,如下所示:food_typenamecolorflavor——“无库存”的事情也会混淆 CSV 文件的一致性。跨度>
  • @match 谢谢,我相信你的建议可以扩展到下面 AlexanderMP 建议的状态机。我去看看。
  • @Pretzel 你是对的,我只是为了自己的学习制作了这个csv文件,所以在这种特殊情况下没有遵循标准的csv格式。

标签: python csv for-loop while-loop


【解决方案1】:

您可以拥有一个状态机来记住您正在阅读的内容

def is_title(row):
  return len(row) == 1 and row[0].upper() == row[0]

current_entity = None
result = {}
for row in reader:
  if is_title(row):
    current_entity = row[0]
  elif current_entity is not None:
    if current_entity not in result:
      result[current_entity] = []
    result[current_entity].append(row)
  else:
    raise RuntimeError("Row doesn't belong to any entity")

另一个问题是您如何处理包含额外值的行。基本上你需要决定哪些属于什么。

这不是 CSV。这介于 CSV 和一些试图理解非常糟糕的数据的 ML 之间,因为预设规则只会让你走这么远。

【讨论】:

  • 感谢您的回复,我需要一些时间来理解和测试您的代码!
  • 慢慢来。如果有任何问题,尽管问,但让我告诉你——你得到了一个非常讨厌的数据集:)
猜你喜欢
  • 1970-01-01
  • 2020-03-25
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多