【问题标题】:Take the content of a list and append it to another list获取列表的内容并将其附加到另一个列表
【发布时间】:2011-11-18 02:31:23
【问题描述】:

我试图了解获取列表的内容并将其附加到另一个列表是否有意义。

我通过循环函数创建了第一个列表,它将从文件中获取特定行并将它们保存在列表中。

然后使用第二个列表来保存这些行,并在另一个文件上开始新的循环。

我的想法是在 for 循环完成后获取列表,将其转储到第二个列表中,然后开始一个新的循环,将第一个列表的内容再次转储到第二个但附加它,所以第二个列表将是在我的循环中创建的所有较小列表文件的总和。仅当满足某些条件时才必须附加该列表。

看起来像这样:

# This is done for each log in my directory, i have a loop running
for logs in mydir:

    for line in mylog:
        #...if the conditions are met
        list1.append(line)

    for item in list1:
        if "string" in item: #if somewhere in the list1 i have a match for a string
            list2.append(list1) # append every line in list1 to list2
            del list1 [:] # delete the content of the list1
            break
        else:
            del list1 [:] # delete the list content and start all over

这有意义吗,还是我应该选择不同的路线?

我需要一些不会占用太多周期的高效工具,因为日志列表很长而且每个文本文件都很大;所以我认为这些列表符合目的。

【问题讨论】:

    标签: python list


    【解决方案1】:

    你可能想要

    list2.extend(list1)
    

    而不是

    list2.append(list1)
    

    这就是区别:

    >>> a = [1, 2, 3]
    >>> b = [4, 5, 6]
    >>> c = [7, 8, 9]
    >>> b.append(a)
    >>> b
    [4, 5, 6, [1, 2, 3]]
    >>> c.extend(a)
    >>> c
    [7, 8, 9, 1, 2, 3]
    

    由于list.extend()接受任意迭代,你也可以替换

    for line in mylog:
        list1.append(line)
    

    通过

    list1.extend(mylog)
    

    【讨论】:

    • 是的,append 是一个元素,extend 就像 concat。
    【解决方案2】:

    查看 itertools.chain 了解一种将许多小列表视为单个大列表(或至少作为单个大可迭代)而不复制较小列表的快速方法:

    >>> import itertools
    >>> p = ['a', 'b', 'c']
    >>> q = ['d', 'e', 'f']
    >>> r = ['g', 'h', 'i']
    >>> for x in itertools.chain(p, q, r):
            print x.upper()
    

    【讨论】:

    • 听起来真的很漂亮!我会看看它,看看我是否可以使用 itertools 替换我已经拥有的代码!
    【解决方案3】:

    回顾之前的答案。如果您有一个带有[0,1,2] 的列表和另一个带有[3,4,5] 的列表,并且您想要合并它们,因此它变成[0,1,2,3,4,5],您可以使用chainingextending,并且应该知道明智地使用它的区别满足您的需求。

    扩展列表

    使用listextend 方法,您可以将元素从一个列表复制到另一个列表。但是,这会导致额外的内存使用,这在大多数情况下应该没问题,但如果您想提高内存效率,可能会导致问题。

    a = [0,1,2]
    b = [3,4,5]
    a.extend(b)
    >>[0,1,2,3,4,5]
    

    链接列表

    相反,您可以使用itertools.chain 连接多个列表,这将返回一个所谓的iterator,可用于遍历列表。这更节省内存,因为它不会复制元素,而只是指向下一个列表。

    import itertools
    a = [0,1,2]
    b = [3,4,5]
    c = itertools.chain(a, b)
    

    创建一个迭代器,它从第一个可迭代对象返回元素,直到它用尽,然后继续下一个可迭代对象,直到所有可迭代对象都用完。用于将连续序列视为单个序列。

    【讨论】:

      【解决方案4】:

      您还可以使用“+”运算符组合两个列表(例如 a、b)。 例如,

      a = [1,2,3,4]
      b = [4,5,6,7]
      c = a + b
      
      Output:
      >>> c
      [1, 2, 3, 4, 4, 5, 6, 7]
      

      【讨论】:

        【解决方案5】:

        这对于您正在尝试做的事情来说似乎相当合理。

        依靠 Python 完成更多繁重工作的稍短版本可能是:

        for logs in mydir:
        
            for line in mylog:
                #...if the conditions are met
                list1.append(line)
        
            if any(True for line in list1 if "string" in line):
                list2.extend(list1)
            del list1
        
            ....
        

        (True for line in list1 if "string" in line) 迭代 list 并在找到匹配项时发出 Trueany() 使用短路评估在找到第一个 True 元素后立即返回 Truelist2.extend()list1 的内容追加到末尾。

        【讨论】:

        • any(True for line in list1 if "string" in line) 更简洁地写成any("string" in line for line in list1)
        • 好点,@KarlKnechtel,尽管它们略有不同。您的版本总是发出 something,True 或 False。我的只发出一个 True。我不知道这些基准是如何得出的,也不知道是否存在足够的差异。
        • 在这两种情况下,any 都会收到一个生成器;任何地方都没有构造 True 或 False 值的列表。我的版本返回更多的东西供any 检查,但作为回报不在生成器本身做同样的检查。我想这是一次洗礼,但timeit 在这里是权威的,而不是我。 :)
        【解决方案6】:

        使用map()reduce() 内置函数

        def file_to_list(file):
             #stuff to parse file to a list
             return list
        
        files = [...list of files...]
        
        L = map(file_to_list, files)
        
        flat_L = reduce(lambda x,y:x+y, L)
        

        最小的“for循环”和优雅的编码模式:)

        【讨论】:

          【解决方案7】:

          您可以简单地连接两个列表,例如:

          list1 = [0, 1]
          list2 = [2, 3]
          list3 = list1 + list2
          
          print(list3)
          >> [0, 1, 2, 3]
          

          【讨论】:

            【解决方案8】:

            如果我们有如下列表:

            list  = [2,2,3,4]
            

            两种方法将其复制到另一个列表中。

            1.

            x = [list]  # x =[] x.append(list) same 
            print("length is {}".format(len(x)))
            for i in x:
                print(i)
            
            length is 1
            [2, 2, 3, 4]
            

            2.

            x = [l for l in list]
            print("length is {}".format(len(x)))
            for i in x:
                print(i)
            
            length is 4
            2
            2
            3
            4
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-01-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-04-12
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多