【问题标题】:Python groupby to split list by delimiterPython groupby 按分隔符拆分列表
【发布时间】:2018-06-18 05:33:42
【问题描述】:

我对 Python (3.6) 很陌生,并且很难理解 itertools groupby。 我有以下包含整数的列表:

    list1 = [1, 2, 0, 2, 3, 0, 4, 5, 0]

但列表也可以更长,并且“0”不必出现在每对数字之后。它也可以在 3、4 或更多数字之后。我的目标是将此列表拆分为子列表,其中“0”用作分隔符并且不会出现在任何这些子列表中。

    list2 = [[1, 2], [2, 3], [4, 5]]

这里已经解决了一个类似的问题: Python spliting a list based on a delimiter word 答案 2 似乎对我有很大帮助,但不幸的是它只给了我一个 TypeError。

    import itertools as it

    list1 = [1, 2, 0, 2, 3, 0, 4, 5, 0]

    list2 = [list(group) for key, group in it.groupby(list1, lambda x: x == 0) if not key]

    print(list2)

文件“H:/Python/work/ps0001/example.py”,第 13 行,在 list2 = [list(group) for key, group in it.groupby(list, lambda x: x == '0') if not key]

TypeError: 'list' 对象不可调用

我会很感激任何帮助,并且很高兴最终了解 groupby。

【问题讨论】:

  • 您不应该将您的自定义列表命名为“列表”,因为这是一个关键字。使用“mylist”/“onelist”等。
  • list 是保留关键字。将 list = [1, 2, 0, 2, 3, 0, 4, 5, 0] 重命名为 list1 或其他任何名称。
  • 谢谢!我更改了它并将记住它。

标签: python list split delimiter


【解决方案1】:

您可以在循环中执行此操作,如下面的注释片段所示:

list1       = [1, 2, 0, 2, 3, 0, 4, 5, 0]
tmp,result  = ([],[])   # tmp HOLDS A TEMPORAL LIST :: result => RESULT

for i in list1:
    if not i:
        # CURRENT VALUE IS 0 SO WE BUILD THE SUB-LIST
        result.append(tmp)
        # RE-INITIALIZE THE tmp VARIABLE
        tmp = []
    else:
        # SINCE CURRENT VALUE IS NOT 0, WE POPULATE THE tmp LIST
        tmp.append(i)

print(result) # [[1, 2], [2, 3], [4, 5]]

有效:

list1       = [1, 2, 0, 2, 3, 0, 4, 5, 0]
tmp,result  = ([],[])   # HOLDS A TEMPORAL LIST

for i in list1:
    if not i:
        result.append(tmp); tmp = []
    else:
        tmp.append(i)

print(result) # [[1, 2], [2, 3], [4, 5]]

【讨论】:

    【解决方案2】:

    在您的代码中,您需要将lambda x: x == '0' 更改为lambda x: x == 0,因为您使用的是int 列表,而不是str 列表。

    由于其他人已经展示了如何使用 itertools.groupby 改进您的解决方案,您也可以在没有库的情况下执行此任务:

    >>> list1 = [1, 2, 0, 2, 3, 0, 4, 5, 0]
    >>> zeroes = [-1] + [i for i, e in enumerate(list1) if e == 0]
    >>> result = [list1[zeroes[i] + 1: zeroes[i + 1]] for i in range(len(zeroes) - 1)]
    >>> print(result)
    [[1, 2], [2, 3], [4, 5]]
    

    【讨论】:

      【解决方案3】:

      尝试使用join,然后用0分割

      lst = [1, 2, 0, 2, 3, 0, 4, 5, 0]
      
      lst_string = "".join([str(x) for x in lst])
      lst2 = lst_string.split('0')
      lst3 = [list(y) for y in lst2]
      lst4 = [list(map(int, z)) for z in lst3]
      print(lst4)
      

      在我的控制台上运行:

      【讨论】:

      • 你必须转换回int,列表中的元素是字符串。
      • 它又给了我TypeError: 'list' object is not callable。表达式list(y) 会不会有问题?
      • 请勿使用 list 作为变量名。
      【解决方案4】:

      您可以为此使用正则表达式:

      >>> import ast 
      >>> your_list = [1, 2, 0, 2, 3, 0, 4, 5, 0]
      >>> a_list = str(your_list).replace(', 0,', '], [').replace(', 0]', ']')
      >>> your_result = ast.literal_eval(a_list)
      >>> your_result
      ([1, 2], [2, 3], [4, 5])
      >>> your_result[0]
      [1, 2]
      >>> 
      

      或单行解决方案:

      ast.literal_eval(str(your_list).replace(', 0,', '], [').replace(', 0]', ']'))
      

      【讨论】:

      • 当有可用的本地工具时,对任何事情都使用正则表达式几乎总是一个坏主意/设计。正则表达式有它自己的立场。此外,如果列表变大,将列表更改为字符串,应用正则表达式,再次评估将非常昂贵。
      • 这是非常鲁布戈德堡,非常脆弱。例如,如果列表包含子列表,这将失败。
      【解决方案5】:

      您正在检查“0”(str),但您的列表中只有 0(int)。此外,您使用list 作为第一个列表的变量名,这是 Python 中的关键字。

      from itertools import groupby
      
      list1 = [1, 2, 0, 2, 7, 3, 0, 4, 5, 0]
      list2 = [list(group) for key, group in groupby(list1, lambda x: x == 0) if not key]
      
      print(list2)
      

      这应该给你:

      [[1, 2], [2, 7, 3], [4, 5]]
      

      【讨论】:

      • 它又给了我TypeError: 'list' object is not callable。表达式list(group) 会不会有问题?
      • 您是否将第一个列表的名称更改为“列表”以外的名称?
      • 是的,我在 OP 中将其更改为 list1。我只是通过复制和过去尝试了您的示例,但它仍然给了我这个错误。
      • @schuph 当您将 list 变量传递给 groupby 时,您也必须更改它的引用。而且,它似乎对我有用:repl.it/@sahaysid/GroupByToSplitListOnDelim
      • 重启 Spyder 就可以了! :D
      【解决方案6】:

      使用 zip 返回一个列表元组,稍后将它们转换为列表

      >>> a
      [1, 2, 0, 2, 3, 0, 4, 5, 0]
      >>> a[0::3]
      [1, 2, 4]
      >>> a[1::3]
      [2, 3, 5]
      >>> zip(a[0::3],a[1::3])
      [(1, 2), (2, 3), (4, 5)]
      >>> [list(i) for i in zip(a[0::3],a[1::3])]
      [[1, 2], [2, 3], [4, 5]]
      

      【讨论】:

        猜你喜欢
        • 2011-06-09
        • 1970-01-01
        • 1970-01-01
        • 2018-03-12
        • 1970-01-01
        • 2019-03-27
        • 1970-01-01
        • 2017-12-24
        相关资源
        最近更新 更多