【问题标题】:Altering the format of a list of strings更改字符串列表的格式
【发布时间】:2017-02-05 18:42:49
【问题描述】:

我必须分析地震数据,在开始分析数据之前,我必须更改数据列出方式的格式。我必须更改格式:

14km WSW of Willow, Alaska$2.4
4km NNW of The Geysers, California$0.9
13km ESE of Coalinga, California$2.1
...

到:

["2.4, 14km WSW of Willow, Alaska", "0.9, 4km NNW of The Geysers, California",
"2.1, 13km ESE of Coalinga, California", ...]

我对原始格式的代码(省略了 url)是:

def fileToList(url):
    alist = []
    source = urllib2.urlopen(url)
    for line in source:
        items = line.strip()
        alist.append(items)
    return alist

我正在尝试创建变量幅度和地震定位来重新排列 alist 的格式,但我只是不知道从哪里开始。我对编码很陌生。任何建议都会很棒,谢谢。

【问题讨论】:

    标签: python


    【解决方案1】:

    提示:

    >>> a = "14km WSW of Willow, Alaska$2.4"
    >>> a = a.split("$")   split the string on `$`
    >>> a
    ['14km WSW of Willow, Alaska', '2.4']
    >>> a = a[::-1]        reverse the list    
    >>> a
    ['2.4', '14km WSW of Willow, Alaska']
    >>> ",".join(a)            give jon on `,`
    '2.4,14km WSW of Willow, Alaska'
    

    一个班轮:

    >>> ",".join(a.split("$")[::-1])
    '2.4,14km WSW of Willow, Alaska'
    

    您预期输出的 Pythonic 方式:

    >>> myString = """14km WSW of Willow, Alaska$2.4
    ... 4km NNW of The Geysers, California$0.9
    ... 13km ESE of Coalinga, California$2.1"""
    >>> map(lambda x: ",".join(x.split("$")[::-1]), myString.strip().split("\n"))
    ['2.4,14km WSW of Willow, Alaska', '0.9,4km NNW of The Geysers, California', '2.1,13km ESE of Coalinga, California']
    

    【讨论】:

    • 这有助于以正确的顺序获取信息,首先是地震震级,然后是位置,但由于某种原因,.join() 似乎无法转换信息进入每个地震的字符串列表。
    • 我的输出看起来像:['2.4', '14km WSW of Willow, Alaska']\n ['0.9', '4km NNW of The Geysers, California'] \n['2.1' , '13km ESE of Coalinga, California']\n ... 来自此代码:def fileToList(url): alist = [] source = urllib2.urlopen(url) for line in source: items = line.strip()。 split("$") alist.append(items[::-1]) return alist
    • 我怎样才能得到 ["2.4, 14km WSW of Willow, Alaska", "0.9, 4km NNW of The Geysers, California", "2.1, 13km ESE of Coalinga, California", ... ] 作为我的输出?
    【解决方案2】:

    如果您担心格式化,那么我会使用 collections.namedtuple 作为中间值:

    from collections import namedtuple
    
    Data = namedtuple('Data', ['position', 'magnitude'])
    
    mystr = """14km WSW of Willow, Alaska$2.4
    4km NNW of The Geysers, California$0.9
    13km ESE of Coalinga, California$2.1"""
    
    list_of_data = []
    for line in mystr.split('\n'):   # equivalent to your "for line in source"
        list_of_data.append(Data(*line.split('$')))
    

    这将为您提供以下信息:

    >>> list_of_data
    [Data(position='14km WSW of Willow, Alaska', magnitude='2.4'),
     Data(position='4km NNW of The Geysers, California', magnitude='0.9'),
     Data(position='13km ESE of Coalinga, California', magnitude='2.1')]
    

    这很容易被操纵:

    >>> ['{x.magnitude}, {x.position}'.format(x=x) for x in list_of_data]
    ['2.4, 14km WSW of Willow, Alaska',
     '0.9, 4km NNW of The Geysers, California',
     '2.1, 13km ESE of Coalinga, California']
    

    或按大小排序:

    >>> sorted(list_of_data, key=lambda x: x.magnitude)
    [Data(position='4km NNW of The Geysers, California', magnitude='0.9'),
     Data(position='13km ESE of Coalinga, California', magnitude='2.1'),
     Data(position='14km WSW of Willow, Alaska', magnitude='2.4')
    

    最后,如果您的数据集很大,使用正则表达式可能更有意义。但是使用str.split 解析数据并将其保存在namedtuples 中并不是很容易理解,所以我使用了这种方法。

    【讨论】:

    • 您不需要namedtuple 的开销即可从拆分创建listnamedtuples 的列表也不是 OP 要求的格式。
    • 但是可以创建所请求的格式(参见['{x.magnitude}, {x.position}'.format(x=x) for x in list_of_data])。此外,如果您将namedtuples 视为开销,那么您就犯了一个巨大的错误。在这种情况下,字符串的各个部分都有明确的含义,那么为什么更喜欢未命名的“列表”或“元组”呢?
    • Namedtuple 实际上确实增加了开销:您必须查找 namedtuple 定义。每次访问命名元组中的字段时,不仅有属性查找,还有索引查找。因此,对于您要替换为 namedtuple 属性的列表,您有一个非常实际的开销。见:stackoverflow.com/questions/2646157/…
    • 如果想要快速,任何split 方法都可能不如做一个正则表达式。如果有人想要一个好的数据结构,那么namedtuple 是一个不错的选择,他已经说过他想分析数据。因此,在接下来的步骤中,拥有namedtuple 将比任何“一招制小马”更能帮助他:D
    • 您在正则表达式上是正确的,但由于用户是编码新手,我避免使用正则表达式。我并不反对我对通常对其有用的命名元组进行罚款,但我喜欢限制我的答案以解决用户请求帮助的确切问题。
    【解决方案3】:

    假设您的 source 变量包含以下几行:

    14km WSW of Willow, Alaska$2.4
    4km NNW of The Geysers, California$0.9
    13km ESE of Coalinga, California$2.1
    

    在最简单的情况下,使用 str.splitstr.join 函数就足够了:

    def fileToList(url=''):
        source = urllib2.urlopen(url)
    
        return [', '.join(l.split('$')[::-1]) for l in source.split('\n') if l.strip()]
    
    print(fileToList())
    

    输出应该如下所示:

    ['2.4, 14km WSW of Willow, Alaska', '0.9, 4km NNW of The Geysers, California', '2.1, 13km ESE of Coalinga, California']
    

    【讨论】:

      【解决方案4】:

      您似乎只是想重新排序每个字符串的格式,所以如果您在多行字符串中有初始数据,如下所示:

      earthquake_data = """14km WSW of Willow, Alaska$2.4
      4km NNW of The Geysers, California$0.9
      13km ESE of Coalinga, California$2.1"""
      

      然后你可以在换行符上拆分它以获得字符串列表:

      lines = data.split('\n')
      >>> ['14km WSW of Willow, Alaska$2.4', '4km NNW of The Geysers, California$0.9', '13km ESE of Coalinga, California$2.1']
      

      对于数据列表的每个项目,将其拆分为“$”符号,这将为您留下如下列表:

      split_lines = [l.split('$') for l in lines]
      >>> [['14km WSW of Willow, Alaska', '2.4'], ['4km NNW of The Geysers, California', '0.9'], ['13km ESE of Coalinga, California', '2.1']]
      

      然后,您可以对列表推导中的每个项目使用 str.join() 字符串方法将这些列表中的每一个连接回字符串:

      reformatted_data = [", ".join([l[1], l[0]]) for l in split_lines]
      >>> ['2.4, 14km WSW of Willow, Alaska', '0.9, 4km NNW of The Geysers, California', '2.1, 13km ESE of Coalinga, California']
      

      这一切都包含在一个函数中:

      def reformatStrings(data):
          lines = data.split("\n")
          split_lines = [l.split('$') for l in lines]
          reformatted_data = [", ".join([l[1], l[0]]) for l in split_lines]
          return reformatted_data
      
      
      print(reformatStrings(earthquake_data))
      

      【讨论】:

        猜你喜欢
        • 2012-05-24
        • 2020-03-21
        • 2011-05-04
        • 2011-04-18
        • 2016-06-25
        • 1970-01-01
        • 1970-01-01
        • 2016-09-15
        相关资源
        最近更新 更多