【问题标题】:Splitting elements of list into an array将列表的元素拆分为数组
【发布时间】:2019-10-14 11:10:44
【问题描述】:

我有一个字符串数据集,我需要将字符串的关键部分过滤到一个数组中。

data[0] 给出输出:

['<ellipse cx="32.0" cy="8.0" fill="silver" rx="16.0" ry="16.0" /',
 '<ellipse cx="32.0" cy="56.0" fill="green" rx="32.0" ry="16.0" /',
 '<ellipse cx="8.0" cy="8.0" fill="green" rx="16.0" ry="32.0" /']

我需要创建的是以下数组:

key_data[0] -&gt; [['ellipse' , 32.0, 8.0, 'silver', 16.0, 16.0], [ 'ellipse', 32.0, 56.0, 'green', 32.0, 16.0], ['ellipse', 8.0, 8.0, 'green', 16.0, 32.0]]

任何建议将不胜感激

【问题讨论】:

  • 看起来一个简单的正则表达式应该能够提取你想要的所有位。
  • 不应该在输入的第三个椭圆的末尾有'吗?
  • @Barmar,是的,会编辑这个
  • “椭圆”总是在那里吗?还是可以是不同的数据?如果是这样,请提供一个通用模型......就像@Barmar 所说:一个简单的regex 可能会完成这项工作。查看Regex101 以交互方式构建和测试您自己的。这是我构建正则表达式的首选编辑器。

标签: python arrays string list


【解决方案1】:
import re

data = ['<ellipse cx="32.0" cy="8.0" fill="silver" rx="16.0" ry="16.0" /',
        '<ellipse cx="32.0" cy="56.0" fill="green" rx="32.0" ry="16.0" /',
        '<ellipse cx="8.0" cy="8.0" fill="green" rx="16.0" ry="32.0" /']

re_compile = re.compile(r'<(.*?) cx="(.*?)" cy="(.*?)" fill="(.*?)" rx="(.*?)" ry="(.*?)" /')
result = list(map(lambda x: re_compile.search(x).groups(), data))
print(result)

【讨论】:

    【解决方案2】:

    这是使用正则表达式的一种方法。 re.match

    例如:

    import re
    
    data = ['<ellipse cx="32.0" cy="8.0" fill="silver" rx="16.0" ry="16.0" /', '<ellipse cx="32.0" cy="56.0" fill="green" rx="32.0" ry="16.0" /', '<ellipse cx="8.0" cy="8.0" fill="green" rx="16.0" ry="32.0" /']
    result = []
    for i in data:
        m = re.match(r"\<([a-z]+) \w+=(.*?)\s\w+=(.*?)\s\w+=(.*?)\s\w+=(.*?)\s\w+=(.*?)", i)
        result.append([j.strip('"') for j in m.groups() if j])
    print(result)
    

    输出:

    [['ellipse', '32.0', '8.0', 'silver', '16.0'],
     ['ellipse', '32.0', '56.0', 'green', '32.0'],
     ['ellipse', '8.0', '8.0', 'green', '16.0']]
    

    或使用re.match & re.findall

    例如:

    data = ['<ellipse cx="32.0" cy="8.0" fill="silver" rx="16.0" ry="16.0" /', '<ellipse cx="32.0" cy="56.0" fill="green" rx="32.0" ry="16.0" /', '<ellipse cx="8.0" cy="8.0" fill="green" rx="16.0" ry="32.0" /']
    result = []
    for i in data:
        m = re.match(r"\<([a-z]+)", i)
        attribs = re.findall(r'\w+="(.*?)"', i)
        result.append([m.group(1)] + attribs )
    

    【讨论】:

      【解决方案3】:

      这是一个不使用正则表达式的解决方案。

      a = ['<ellipse cx="32.0" cy="8.0" fill="silver" rx="16.0" ry="16.0" ',
       '<ellipse cx="32.0" cy="56.0" fill="green" rx="32.0" ry="16.0" ',
       '<ellipse cx="8.0" cy="8.0" fill="green" rx="16.0" ry="32.0" ']
      
      d = [i.split() for i in a]
      r = [[j.split('=')[-1] for j in i] for i in d]
      s = [[i.strip('"').lstrip('<') for i in k] for k in r]
      
      # convert to float where possible
      for k in s:
          for i, j in enumerate(k):
              try:
                  k[i] = float(j)
              except ValueError:
                  pass
      
      >>> print(s)
      [['ellipse', 32.0, 8.0, 'silver', 16.0, 16.0],
      ['ellipse', 32.0, 56.0, 'green', 32.0, 16.0],
      ['ellipse', 8.0, 8.0, 'green', 16.0, 32.0]]
      

      【讨论】:

        【解决方案4】:

        如果您不习惯使用正则表达式,您可以使用这段代码。

        从 ast 导入literal_eval

        def return_list(ellipse_list): final_res = [] 对于 ellipse_list 中的椭圆: res = [literal_eval(item.split("=")[1]) if "=" in item else item for item in ellipse[1:-1].split(" ")[:-1]] final_res.append(res)

        return final_res

        【讨论】:

          【解决方案5】:

          Regex是一种更好的方法,但是如果你不想使用它,你可以这样做:

          new_l = []
          for i in data:
              sub_l = []
              el = i.split()
              sub_l.append(el[0][1:])
              for e in el[1:]:
                  x = e.split('=')
                  try:
                      sub_l.append(x[1].strip().strip('"'))
                  except IndexError:
                      continue
              new_l.append(sub_l)
          

          【讨论】:

            【解决方案6】:

            列表的内容看起来像 XML,并且 XML 应该被视为 XML。只剩下最后一个'&gt;'。所以我们可以使用 XML 解析器来处理。

            from lxml import etree
            
            data = ['<ellipse cx="32.0" cy="8.0" fill="silver" rx="16.0" ry="16.0" /',
                    '<ellipse cx="32.0" cy="56.0" fill="green" rx="32.0" ry="16.0" /',
                    '<ellipse cx="8.0" cy="8.0" fill="green" rx="16.0" ry="32.0" /']
            
            
            def parse_element(element):
                # adjust faulty XML if needed
                if not element.rstrip().endswith('>'):
                    element += '>'
            
                # create the XML structure
                doc = etree.XML(element)
            
                # gather all attribute values in a dictionary
                attributes = ['cx', 'cy', 'rx', 'ry', 'fill']
                values = {attribute_name: doc.get(attribute_name) for attribute_name in attributes}
            
                # construct target
                entry = [doc.tag,
                         float(values['cx']),
                         float(values['cy']),
                         values['fill'],
                         float(values['rx']),
                         float(values['ry'])]
            
                return entry
            
            
            result = [parse_element(element) for element in data]
            print(result)
            

            如果属性的顺序发生变化,它仍然会运行。

            【讨论】:

              猜你喜欢
              • 2017-07-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-05-19
              • 1970-01-01
              • 2017-04-25
              相关资源
              最近更新 更多