【问题标题】:Using list comprehension to "merge" a list within a list使用列表推导在列表中“合并”列表
【发布时间】:2015-09-01 13:23:18
【问题描述】:

所以我在一个列表中有列表:

woot = [['abc','efg', '4.3', '5.7', '80085'],['aba','bab', '1.0', '9.0', '3.0'], ... , ... ]

每个嵌套列表都是相同的:前 2 个元素是由字母组成的字符串,其余元素是由数字组成的字符串。

我正在尝试将所有字符串编号转换为浮点数并将每个嵌套列表的字符串编号合并到其自己的列表中(最终成为双嵌套列表),因此最终结果如下所示:

final = [['abc','efg', [ 4.3, 5.7, 80085]], ['aba','bab', [ 1.0, 9.0, 3.0]] , ... , ... ]

所以我的方法是使用列表推导将字符串数字转换为浮点数并将这些数字和字母字符串拆分为单独的列表并合并它们。

bloop = [[float(x) for x in y[2:]] for y in woot]

bleep = [[x for x in y[:2]] for y in woot]

所以我最终得到:

bloop = [[ 4.3, 5.7, 8005.0],[ 1.0, 9.0, 3.0], ... , ... ]
bleep = [['abc','efg'],['aba','bab'], ... , ... ]

这就是我崩溃的地方,似乎无法“合并”这些列表。

final = []
for i in bleep:
    final.append(i)
for i in bloop:
    final.append(i)

不幸的是,这只是将列表放在一起:

[['abc','efg'],['aba','bab'],[ 4.3, 5.7, 8005.0],[ 1.0, 9.0, 3.0]]

【问题讨论】:

  • 完全按照您的要求完成了...
  • 旁注:[[x for x in y[:2]] for y in woot] 等价于[y[:2] for y in woot]
  • 另一个旁注:尽量不要滥用列表理解。在大多数情况下,它可以为您节省一些字符,但也可能使您的代码不可读且速度慢。
  • 你是建议我坚持写出循环还是使用其他功能?我正在尝试练习一些操作嵌套循环的思维障碍,而不是求助于使用图书馆中的一些魔法工具,尽管现在我开始对列表理解感到疯狂,因为它似乎很容易失去我的思路用它。

标签: python list


【解决方案1】:

怎么样:

final = [x[:2] + [[float(f) for f in x[2:]]] for x in woot]

【讨论】:

    【解决方案2】:

    简化你的逻辑:

    final = []
    for l in woot:
        adjusted = l[:2]
        adjusted.append( [float(x) for x in l[2:]] )
        final.append(adjusted)
    

    首先,调试的难度是编写代码的两倍。 因此,如果你尽可能巧妙地编写代码,你就是 定义,不够聪明,无法调试。

       — Brian W. Kernighan and P. J. Plauger in The Elements of Programming Style.
    

    参考:http://quotes.cat-v.org/programming/

    【讨论】:

    • 我同意你的观点,但列表理解并不是太“聪明”。它们是 Python 的肉和 3 种蔬菜。在这种情况下,产生所需输出的列表理解是微不足道的。
    • 您能否详细说明您所说的不太“聪明”是什么意思?
    • @user155876 :这是对这个答案中“尽可能巧妙地编写代码”的引用的引用。我的观点是,列表推导是 Python 语言的一项基本功能,它们不一定很聪明。当然,编写一个难以破译的列表解析很容易,但是,在这种特定情况下,所需的列表解析一点也不复杂。
    • 我引用了这句话,因为最初的问题是使用两个列表推导来制作两个列表,然后尝试再次将它们合并在一起。当列表推导简单明了时,它们本身就不是问题。实际上,我赞成 Delgan 的原始答案,因为它看起来不错、简单且易于理解。 (我在回答中保留了一个简单的列表理解!)
    • 我最讨厌的一个:变量l。它看起来太像1。 (我曾经发现一个包含ll1l12ll2 的程序,其中最后一个是错误!)除此之外,我勉强喜欢它而不是列表理解,尽管总的来说我喜欢列表推导式。
    【解决方案3】:

    这是一个列表推导式,可产生您所需的输出:

    >>> [t[:2] + [[float(f) for f in t[2:]]] for t in woot]
    [['abc', 'efg', [4.3, 5.7, 80085.0]], ['aba', 'bab', [1.0, 9.0, 3.0]]]
    

    【讨论】:

      【解决方案4】:

      这似乎有效:

      final = [l[0:2]+[list(map(float,l[2:]))] for l in woot]
      

      但也许我作弊是因为我使用了map ...

      【讨论】:

      • 使用list(map()) 与使用列表推导并没有什么不同。它会产生同样的结果,而且真的不是“作弊”。
      • 当然,但是他问如何使用列表理解,而我没有完全使用列表理解。我知道这不是“作弊”,这只是一种不同的方式。
      【解决方案5】:

      使用你的哔哔声

      bloop = [[ 4.3, 5.7, 8005.0],[ 1.0, 9.0, 3.0]]
      bleep = [['abc','efg'],['aba','bab']]
      final =[]
      for i in range(len(bleep)):
          final.append(bleep[i]+[bloop[i]])
      print final
      

      【讨论】:

        【解决方案6】:

        下面的想法使用列表理解和切片语法将每个子列表拆分为一个包含 sub-0、sub-1 的列表,然后是索引 2..n 中的项目列表。这是使用list 类型的+ 运算符完成的。

        我使用了map,而不是简洁的内在理解,但如果你使用[float(ysub) for ysub in y[2:]],则没有功能上的区别。

        woot = [['abc','efg', '4.3', '5.7', '80085'],['aba','bab', '1.0', '9.0', '3.0']]
        print [y[:2] + [map(float, y[2:])] for y in woot]
        [['abc', 'efg', [4.3, 5.7, 80085.0]], ['aba', 'bab', [1.0, 9.0, 3.0]]]
        

        【讨论】:

        • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
        【解决方案7】:

        这里有很多很好的答案,我只是想指出扩展语法通常更好。另外,尽量避免嵌套列表推导。为每一层嵌套编写一个函数并在每一层内放置一个列表理解几乎总是更清晰。所以我会这样做:

        def process_list(l) :
            #processes the sub list
            new_list = l[:2]
            new_list.extend([float(x) for x in l[2:])
            return new_list
        
        result = [process_list(l) for l in original_list]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-13
          • 2020-10-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多