【问题标题】:In Python 3, how can I extract a list of number from a file at a specific URL?在 Python 3 中,如何从特定 URL 的文件中提取数字列表?
【发布时间】:2013-12-06 09:43:01
【问题描述】:

网址是:http://robjhyndman.com/tsdldata/data/cryer2.dat

这是我需要达到的目标:

'''(str) -> reader
Open the URL url, read past the three-line header, and 
return the open reader.'''

这是我尝试过的:

list1=[]

f=urllib.request.urlopen('http://robjhyndman.com/tsdldata/data/cryer2.dat')

data=f.read()

datasplit=data.split()

for x in datasplit:
    if x.isdigit():
        list1.append(datasplit)

print (list1)

它仍然没有显示我想要的。我想要的是在一个名为list1list 中获取所有数字,以便我可以进行进一步的操作。

【问题讨论】:

  • @synthesizerpatel:不,他没有。在 Python 3 中,他想要urllib.request.urlopen,就像他一样。即使在 Python 2 中,您也不想使用自 2.6 以来已弃用的 urllib.urlopen
  • 糟糕。我很抱歉。我对 OP 进行了分区。
  • 你真的想把这个二维数组读成这样的平面列表吗?
  • @abarnert 在保留数据的原始结构方面并没有太多有用的元数据——它仍然是一个按月排列的顺序列表。如果这就是你所需要的,何必呢?
  • @selllikesybok:在原来的结构中,每一行是一年,每一列是一个月。你不认为这是有意义的信息吗?

标签: python string methods python-3.x numbers


【解决方案1】:

isdigitdatasplit 中除“1964”之外的所有项目返回False,因为数字是float 值(包含.),而不是intisdigit 只检查数字。

另外,您可能不想将整个 datasplit 列表添加到您的结果中,而只想添加实际项目。

您可以在拆分前跳过前两行(使用readline),只需将结果中的项目转换为float

f=urllib.request.urlopen('http://robjhyndman.com/tsdldata/data/cryer2.dat')
f.readline()
f.readline()
list1 = [float(v) for v in f.read().split()]

【讨论】:

    【解决方案2】:

    正如所写,您正在查看对于列表datasplit 中的任何元素,该元素是否仅由数字组成。如果是这种情况,那么您将整个datasplit 附加到list1 中。唯一全为数字的元素是 '1964',所以你会得到一个附加的整个列表的副本,就是这样。

    在这种情况下,您应该做的是:

    list1=[]
    
    f=urllib.request.urlopen('http://robjhyndman.com/tsdldata/data/cryer2.dat')
    
    data=f.read()
    
    datasplit=data.split()
    
    for x in datasplit:
        if '.' in x:
            list1.append(x)
    
    print (list1)
    

    它的作用是查看是否有'.'在datasplit 的当前元素中(因为您只想要数据,并且所有数据都包含一个“。”字符,其他什么都没有)。然后,如果if 条件的计算结果为True,它只会将当前元素附加到list1,这就是您想要的。

    请记住,最后,您仍然会得到一个字符串列表 - 要将它们处理为数字,您必须稍后将它们转换。

    编辑添加:

    如果您希望list1 实际上有数字对象而不是字符串,对我的回答最简单的更改是更改附加语句:

    list1.append(float(x))
    

    这会将x 的值转换为float,因此您现在可以对list1 的内容进行数值运算。

    再次编辑添加:

    只是为了好玩,如果你是单线的忠实粉丝,你可以这样做:

    list1=[e for e in urllib.request.urlopen('http://robjhyndman.com/tsdldata/data/cryer2.dat').read().split() if '.' in e]

    但这充其量会使错误处理变得困难。作为一般规则,我不建议在列表推导中包含 I/O。

    【讨论】:

    • urllib 包没有请求方法(或函数);它有一个request 模块,它有一个urlopen 函数。
    • 另外,检查'.' in 的有效浮点数是非常具体的,而且很奇怪,可能会使任何在阅读代码时没有直接查看文件的读者感到困惑。
    • 是的,错过了 Py3 位,已编辑。此外,他不是在寻找浮点数,而是在寻找从文本中收集一组标记,这些标记都符合一组特定的标准。当然,re 在这里会有点矫枉过正。他想解析一个页面,而不是写一个通用的解析器。
    • “我想要的是获取名为 list1 的列表中的所有数字”。所以是的,他正在寻找花车。
    • 他想要数据——他称之为“数字”,但实际上它们不是数字,而是字符串。他在这里寻找的字符串恰好是精度为 1 的浮点数的字符串表示形式。因此,正确的方法是使用字符串操作来获取它们,然后将其转换为正确的对象以用于后续处理步骤。跨度>
    【解决方案3】:

    一般来说,如果有一种描述格式的简单方法,则根据该格式进行解析比忽略它并尝试以其他方式恢复信息更清晰。而且这里的格式很简单:它有 3 个你想忽略的标题行,然后它有一个以空格分隔的 CSV 表格(或者,如果你愿意,也可以是固定宽度的列)。

    如果您使用该格式,则数字是“表格所有行中的所有列”。如果您忽略格式,则必须依赖于这样一个事实,即列中的所有值恰好具有页面上没有其他任何内容的特定结构,这更容易出错(就像您所做的那样),并且对于阅读您的代码的人来说,如果他没有直接查看文件,则更难理解。

    那么,如何解析以空格分隔的表?使用csv 模块,或逐行读取split 每行。我将展示两种方式:

    f=urllib.request.urlopen('http://robjhyndman.com/tsdldata/data/cryer2.dat')
    for header in range(3):
        next(f)
    list1 = [float(column) for row in f for column in row.split()]
    
    f=urllib.request.urlopen('http://robjhyndman.com/tsdldata/data/cryer2.dat')
    for header in range(3):
        next(f)
    reader = csv.reader(f, delimiter=' ', skipinitialspace=True)
    list1 = [float(column) for row in reader for column in row]
    

    【讨论】:

      猜你喜欢
      • 2021-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2017-06-06
      相关资源
      最近更新 更多