【问题标题】:Expanding a block of numbers in Python在 Python 中扩展一个数字块
【发布时间】:2015-05-12 20:47:54
【问题描述】:

在我问之前,我做了一些谷歌搜索,但无法找到答案。

我的情况是这样的: 将数字列表传递给脚本,通过文件以 \n 分隔,或通过命令行 arg 以逗号分隔。这些数字可以是单数,也可以是块,如下所示:

文件:

1
2
3
7-10
15
20-25

命令行参数:

1, 2, 3, 7-10, 15, 20-25

两者都在同一个列表[]中。我想扩展 7-10 或 20-25 块(显然在实际脚本中这些数字会有所不同)并将它们附加到一个新列表中,最终列表如下所示:

['1','2','3','7','8','9','10','15','20','21','22','23','24','25']

我知道 .append(range(7,10)) 之类的东西在这里可以帮助我,但我似乎无法找出原始 list[] 的哪些元素需要扩展。

所以,我的问题是: 给定一个列表[]:

['1','2','3','7-10','15','20-25'],

我怎样才能得到一个列表[]:

 ['1','2','3','7','8','9','10','15','20','21','22','23','24','25']

【问题讨论】:

标签: python list python-2.7 variable-expansion


【解决方案1】:

输入:

arg = ['1','2','3','7-10','15','20-25']

输出:

out = []
for s in arg:
    a, b, *_ = map(int, s.split('-') * 2)
    out.extend(map(str, range(a, b+1)))

或者(在 Python 2 中):

out = []
for s in arg:
    r = map(int, s.split('-'))
    out.extend(map(str, range(r[0], r[-1]+1)))

【讨论】:

    【解决方案2】:

    假设你得到了这份清单:

    L = ['1','2','3','7-10','15','20-25']
    

    并且您想扩展其中包含的所有范围:

    answer = []
    for elem in L:
        if '-' not in elem:
            answer.append(elem)
            continue
        start, end = elem.split('-')
        answer.extend(map(str, range(int(start), int(end)+1)))
    

    当然,有一个方便的单线:

    answer = list(itertools.chain.from_iterable([[e] if '-' not in e else map(str, range(*[int(i) for i in e.split('-')]) + [int(i)]) for e in L]))
    

    但这利用了 python2.7 中泄漏变量的性质,我认为这在 python3 中不起作用。此外,它并不是最易读的代码行。所以如果我是你,我不会真的在生产中使用它……除非你真的讨厌你的经理。

    参考:append()continuesplit()extend()map()range()list()itertools.chain.from_iterable()int()

    【讨论】:

    • 我完全同意你的解决方案,我正要说同样的话,但地图的兴趣是什么?
    • 完美运行!谢谢!
    • @AlexandreMazel:map 在 python2 中返回一个列表,所以它节省了我的嵌套列表理解
    • 但是范围也返回一个列表...哦,是的,我们想要一个字符串列表而不是一个 int 列表。我现在明白了!
    【解决方案3】:

    好的旧地图+reduce会派上用场:

    >>> elements = ['1','2','3','7-10','15','20-25']
    >>> reduce(lambda original_list, element_list: original_list + map(str, element_list), [[element] if '-' not in element else range(*map(int, element.split('-'))) for element in elements])
    ['1', '2', '3', '7', '8', '9', '15', '20', '21', '22', '23', '24']
    

    除了你想让 20-25 也包含 25 之外,这会起到作用......所以这里有更多的汤:

    reduce(
        lambda original_list, element_list: original_list + map(str, element_list), 
        [[element] if '-' not in element 
         else range(int(element.split('-')[0]), int(element.split('-')[1]) + 1) 
         for element in elements])
    

    现在,即使这可行,您最好还是使用一些 for 循环。这就是他们在 python 3 中删除 reduce 的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-17
      • 2015-01-27
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      相关资源
      最近更新 更多