2016-03-03 53 views
4

我以这种形式有一个清单,输入:冷凝多个列表综合

open_info = ['Cube 1, 9:30am to 10:00am, Thursday, March 3, 2016', 'Cube 2, 5:00pm to 5:30pm, Thursday, March 3, 2016'] 

我想通过这些信息来分析建立在这种形式的一个新的列表:

open_times = [[9, 30, 'am'],[5, 0, 'pm']] 

与时针第一个指数,第二个分钟,第三个指数am/pm。我只记录每个列表元素的第一次值,因为我处理的时间间隔总是30分钟。

我已经通过下面的Python列表理解做到了这一点:

open_times = [x.split(",")[1].replace(" ","").split("to") for x in open_info] 
open_times = [x[0].split(":")+x[1].split(":") for x in open_times] 
open_times = [[int(x[0]),int(x[1][:2]),x[1][2:]] for x in open_times] 

我想知道是否有创建嵌套列表理解了所有这些的。我已经看过python文档并阅读了关于这个主题的一些博客,但是我仍然无法完成这个任务。

+1

你会反对非列表理解的解决方案?你知道吗,以便人们能够正确地消化实际的问题?作为进一步的问题,您希望列表的长度是多少? – Makoto

+0

回应上述评论,你能解释为什么你想/需要使用列表解析而不是更传统的(和可读的)解析函数吗? –

+0

我不会全都反对。我对python比较陌生,所以我试图通过练习更多地了解我遇到的困难。我知道这个解决方案很混乱,所以我来到这里。为了回答你的其他问题,列表长度是可变的,但它总是在0到几百之间。 @Makoto –

回答

2

您可以使用下列内容:

open_info = ['Cube 1, 9:30am to 10:00am, Thursday, March 3, 2016', 'Cube 2, 5:00pm to 5:30pm, Thursday, March 3, 2016'] 

answer = [[int(s.split(':',1)[0][-2:]), int(s.split(':')[1][:2]), 
      s.split(':')[1][2:4]] for s in open_info] 
print(answer) 

输出

[[9, 30, 'am'], [5, 0, 'pm']] 

在这种情况下,但是,它可能更容易阅读使用map代替list理解:

def func(s): 
    hour = int(s.split(':')[0][-2:]) 
    minute = int(s.split(':')[1][:2]) 
    suffix = s.split(':')[1][2:4] 
    return [hour, minute, suffix] 

answer = map(func, open_info) 
print(answer) 

输出

[[9, 30, 'am'], [5, 0, 'pm']] 
2

要回答如何“鸟巢”名单解析,你可能会做这行1和2相结合的问题....

open_times = [y[0].split(":")+y[1].split(":") for y in [x.split(",")[1].replace(" ","").split("to") for x in open_info]] 

...但这是非常的混乱。这3条线更容易理解和更清洁。你也可以考虑把它写成一系列的循环,因为在理解中有很多内容会更清晰。

2

您可以使用正则表达式提取时间:

>>> import re 
>>> 
>>> [[int(val) if val.isdigit() else val for val in re.search(r'(\d+):(\d+)(am|pm)',item, re.I).groups()] for item in open_info] 
[[9, 30, 'am'], [5, 00, 'pm']] 

但不是,它可能引发AttributeError如果是的话,如果你不知道,你可以我们try-except表达不能的正则表达式匹配来处理错误。

times = [] 
for item in open_info: 
    match = re.search(r'(\d+):(\d+)(am|pm)',item, re.I) 
    try: 
     h, m, b = match.groups() 
    except (AttributeError, ValueError): 
     pass # or append a proper value to times, instead. 
    else: 
     times.append([int(h), int(m), b]) 
    times.append(match) 
+0

不错,删除评论;) –

2

而是推动全部列出理解expresion您可以简单地创建处理功能的逻辑。

为了提高可读性,我重命名了一些值。

def extract(s): 
    time_from, time_to = s.split(",")[1].replace(" ", "").split("to") 
    hour, min_am_pm = time_from.split(":") 
    min = min_am_pm[:2] 
    am_pm = min_am_pm[2:] 
    return [int(hour), int(min), am_pm] 


open_info = ['Cube 1, 9:30am to 10:00am, Thursday, March 3, 2016', 'Cube 2, 5:00pm to 5:30pm, Thursday, March 3, 2016'] 
open_times = [extract(x) for x in open_info] 
-1
from csv import reader 
answer = [[int(a), int(b[:2]), c[2:]] for a, b, c in (inf[1].split(":") 
      for inf in reader(open_info, skipinitialspace=True))] 

里面居然符合您的预期输出:

[[9, 30, 'am'], [5, 0, 'pm']] 

一个简单的功能将是一个更好的主意,也不需要不断保持反复分裂同一行:

def spl(l): 
    for inf in l: 
     a, b, c = inf.split(", ", 2)[1].split(":", 2) 
     yield [int(a), int(b[:2]), c[2:]] 

print(list(spl(open_info))) 

输出:

[[9, 30, 'am'], [5, 0, 'pm']] 

或者让CSV LIB解析项目:

from csv import reader 

def spl(l): 
    for inf in reader(l, skipinitialspace=True): 
     a, b, c = inf[1].split(":", 2) 
     yield [int(a), int(b[:2]), c[2:]] 
print(list(spl(open_info)))