【问题标题】:Turning a list with only strings into sublists with strings and floats in python在python中将只有字符串的列表变成带有字符串和浮点数的子列表
【发布时间】:2017-10-11 22:22:29
【问题描述】:

我真的在为编写 python 代码而苦苦挣扎。任何帮助将不胜感激。我需要编写代码的功能如下。由于数字是输入中的字符串,我知道我不能以某种方式按学生的姓名分开,我想我必须以某种方式将数字转换为 int/float,然后以某种方式按名称将列表分成子列表(即按字符串) 但我不知道如何做到这一点。我知道我可以使用 map(int, ) 将某些内容转换为 int,但它似乎不起作用,并且等级数(即我需要转换为浮点数)可能因任何输入而异

谢谢!

代码:

def string_list(L):

    '''(list of str) -> list of list
    Given a list of strings where each string has the format:
    'name, grade, grade, grade, ...' return a new list of 
    lists where each inner list has the format :
    [name (str), grade, grade, grade, ...] where the name 
    is a string and the grades are floats.
    >>> string_list(['Joe, 60, 90, 80', 'Harry, 60, 70', 'Jill, 98.5, 100, 95.5, 98'])
    [['Joe', 60.0, 90.0, 80.0], ['Harry', 60.0, 70.0], ['Jill', 98.5, 100.0, 95.5, 98.0]]
    '''

【问题讨论】:

  • 尝试分解问题。你会得到一个大字符串,其中包含姓名和成绩。你怎么能把这些碎片分开? (提示:查看输入字符串的格式!)
  • 感谢您的提示!每个人的名字和他们的成绩都是一个单独的字符串,所以我会看看我是否可以以某种方式拆分这些字符串中的每一个,然后从那里将数字转换为 int。
  • 为了好玩(并提醒您我们在 Python 中使用它是多么容易......)我 implemented this in Haskell。公平地说,我确实重新实现了Data.Text 包中存在的splitOnstrip。我打算没有导入,但发现定义 Data.Char(isSpace) 是……乏味的。

标签: python python-3.x


【解决方案1】:
def string_list(L):
    final_list = []
    for element in L:
        new_entry = element.split(',') # Split on commas; returns a list of strings
        new_entry = [x.strip() for x in new_entry] # Remove whitespace from each string in list
        new_entry[1:] = [float(x) for x in new_entry[1:]] # Cast all entries but the first to float
        final_list.append(new_entry)
    return final_list

【讨论】:

  • 非常感谢您提供代码并添加# cmets 关于每一行的作用,所以我知道发生了什么。我会试试这个!
  • 再次感谢您提供代码!关于它只有两个问题,当您编写 element.split(',') 时,为什么它在字符串之间以逗号分隔而不是在字符串中以逗号分隔?由于字符串是不可变的,甚至可以在字符串中以逗号分隔吗?其次,当你使用“元素”这个词时,还能用其他词吗?为了测试这一点,我用 elxment 代替了 element 并且它仍然有效这是否意味着 element 可以是任何词?如果它可以是任何词,它究竟是什么意思/做什么?除此之外,我理解其余的谢谢!
  • 它在字符串中以逗号分隔。 element 是原始列表的一个元素,例如'Joe, 60, 90, 80'element.split(',') 返回一个字符串列表,但它们包含空格,因此附加了 strip 命令。我将splitstrip 分成两行以使其更清晰。
【解决方案2】:

解决方案

一定要爱上神奇的 oneliner 列表理解!

[[float(val) if val.strip().isdigit() else val.strip() for val in person.split(',')] for person in L]

相同的列表理解,但适用于窄屏幕:

 [[float(val) if val.strip().isdigit() else val.strip() 
      for val in person.split(',')]  
      for person in L ]

用法

你可以像这样加入你的函数:

def string_list(L):
    return [[float(val) if val.strip().isdigit() else val.strip() for val in person.split(',')] for person in L]

然后像这样使用它:

>>> L = ["Joe, 60, 90, 80", "Harry, 60, 70", "Jill, 98.5, 100, 95.5, 98"]
>>> string_list(L)
[['Joe', 60.0, 90.0, 80.0],
 ['Harry', 60.0, 70.0],
 ['Jill', '98.5', 100.0, '95.5', 98.0]]

故障

列表推导很棒但是很丑!所以让我们把这个庞然大物分解成相应的部分:

for person in L]

对于我们列表中的每个项目(例如"Joe, 60, 90, 80"

for val in person.split(',')

如果我们将这些字符串中的每一个拆分成一个字符串列表,使得 "Joe, 60, 90, 80"-> ["Joe","60","90","80"] 并存储迭代每个元素("Joe""60" 等)将每个值存储为 val

float(val) if val.strip().isdigit() else val.strip()

如果val 仅包含数字字符 (.isdigit()),则将其转换为浮点数。否则,返回字符串(没有空格字符,如.strip()

[[<code> for val in person.<more>] for person in L] 

内括号将人物的元素分组,没有它们你只会得到一个字符串列表。

如果您想要一个列表,您需要像这样重新排序for &lt;thing&gt; in &lt;list&gt;

 [float(val) if val.strip().isdigit() else val.strip() 
     for person in L
     for val in person.split(',') ]

【讨论】:

  • 非常感谢您提供的代码和出色的细分!
  • 谢谢!故障实际上与我制作它的方式相反,所以我想我会展示我的工作。只是一个快速的旁注,一个衬里很棒,但在长期(时间)代码中不是超级可持续的。对于生产代码,您确实希望确保性能提升超过复杂性(调试它们)。
猜你喜欢
  • 1970-01-01
  • 2013-10-21
  • 1970-01-01
  • 2022-09-29
  • 2019-08-05
  • 2018-09-07
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
相关资源
最近更新 更多