【问题标题】:Writing a sorted csv file from a changing list of strings. Python 2.7从不断变化的字符串列表中写入排序的 csv 文件。蟒蛇 2.7
【发布时间】:2019-06-08 10:38:02
【问题描述】:

我有大量由不同值组成的字符串(如电话号码、姓名等) 每个字符串总共有 10 个可用值,但每个字符串可能只有其中一些,可能有 0,也可能有全部。 我正在尝试找到一种方法来打开一个包含 10 列的 csv 文件(作为我已经知道的可能值),并将每个字符串的每个值写入相应的“单元格”中,或者在需要时将单元格留空。

例如:

str1=
name1
phonenum1
address1
email1

str2=
name2
phone2
email2


str3=
name3
adress3
email3

我在这个例子中寻找的结果应该是这样的:

name  phonenum  adress  email
name1 phonenum1 adress1 email1
name2 phonenum2         email2
name3           adress3 email3

我尝试将字符串拆分为列表,检查其中的每个项目以查找其适当的列,并将其写入它应该转到的特定单元格中,但我还没有找到写入特定单元格的方法到值的“类型”(在这种情况下是电话号码、姓名等)。 我找到了一些在特定集合单元格中重写现有 csv 的部分答案(例如第 3 列中的所有单元格,或仅第 4 列中的第 3 行),我无法成功地重新实现我的目标。

我遇到的另外两个困难是,1. 一些值中包含逗号。 以及 2. 如何成功识别缺失值以保持他的单元格为空,在上面的示例中 - 我如何识别我缺失的值是电话号码而不是姓名或地址?

【问题讨论】:

  • 对于 1,csv 格式提供 quoting 来保护字段内的分隔符。对于 2,您知道您的输入格式,但我不知道,所以我无法帮助您。

标签: python python-2.7 csv


【解决方案1】:
  • 使用 Numpy 的 genfromtxt() 方法正确读取 CSV 文件,它会为您完成所有的分隔和逗号处理
  • 定义一个行类,其中包含用于不同值的原始槽和作为默认值的空白
  • 根据您的特定需求覆盖 __str__ 方法

【讨论】:

    【解决方案2】:

    假设您的数据如下所示:

    str1 = """
    Adam
    +48100200300
    Street 2, Dublin
    adam@adam.com
    """
    
    str2 = """
    Eva
    48100000000
    eva@eva.com
    """
    
    str3 = """
    Tom Jr
    Street 1, London
    tom@tom.com
    """
    
    data = [str1, str2, str3]
    

    让我们定义您期望的字段:

    field_names = [
        'name',
        'phone',
        'email',
        'address',
    ]
    

    因为在示例中您没有识别字段,并且我看到可能是不同的组合, 那么我们需要识别字段包含什么。

    让我们编写简单的解决方案(您肯定需要更复杂的识别方法 - 但这是一个示例)

    import re
    
    def recognize_field_name(line):
        if not line:
            return
        if re.fullmatch('\\+?[0-9]+', line):
            return 'phone'
        if '@' in line:
            return 'email'
        if ',' in line:
            return 'address'
        return 'name'
    

    然后让我们创建输入数据:

    results = []
    
    for one_string in data:
        result = {}
        for l in one_string.split("\n"):
            value = l.strip()
            field_name = recognize_field_name(value)
            if field_name:
                result[field_name] = value
        results.append(result)
    

    最后我们可以存储它:

    import csv
    
    with open("/tmp/out.csv", "w") as csv_file:
        writer = csv.DictWriter(csv_file, fieldnames=field_names)
        for r in results:
            writer.writerow(r)
    
    with open("/tmp/out.csv") as show:
        print(show.read())
    

    这将产生:

    Adam,+48100200300,adam@adam.com,"Street 2, Dublin"
    Eva,48100000000,eva@eva.com,
    Tom Jr,,tom@tom.com,"Street 1, London"
    

    此解决方案是用 Python 3 编写的,但应该很容易根据您 (2.7) 的需要对其进行修改。

    【讨论】:

      猜你喜欢
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-20
      • 2014-05-16
      • 2016-06-15
      相关资源
      最近更新 更多