【问题标题】:Duplicate each member in a list复制列表中的每个成员
【发布时间】:2011-01-27 18:58:21
【问题描述】:

我想写一个函数来读取列表[1,5,3,6,...] 并给出[1,1,5,5,3,3,6,6,...]。 知道怎么做吗?

【问题讨论】:

  • 听起来像家庭作业。有比复制元素更好的方法来处理列表。
  • 我知道这个问题已经有 10 多年的历史了,但我真的很讨厌这些“听起来像家庭作业”的 cmets。谁在乎需求从何而来?在“现实世界”中使用此方法的一个示例是,例如,当您只有一个初步样本但需要查看它在更大列表中的表现时,您需要增加测试数据的大小。

标签: python list duplicates


【解决方案1】:
>>> a = [1, 2, 3]
>>> b = []
>>> for i in a:
    b.extend([i, i])


>>> b
[1, 1, 2, 2, 3, 3]

>>> [a[i//2] for i in range(len(a)*2)]
[1, 1, 2, 2, 3, 3]

【讨论】:

  • 您也应该在 Python 2 中使用// 进行楼层划分。
  • @Mike:当然你是对的,当然/ 部门会确保返回int
【解决方案2】:
>>> a = range(10)
>>> [val for val in a for _ in (0, 1)]
[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9]

注意_ 传统上用作占位符变量名,您不想对变量的内容做任何事情。在这种情况下,它只是用于为外循环的每次生成两个值。

要将其从列表转换为生成器,请将方括号替换为圆括号。

【讨论】:

  • _ 现在用于 i18n/l10n (google)。我仍然倾向于使用它if 我知道这个模块中不会有 i18n。否则我(会)使用__(两个下划线)。
  • 为了清楚起见,我会选择range(2) 而不是(0, 1)
  • @M.I.Wright 我试过for _ in (_, _) 来反驳你的清晰度,但幸运的是它不起作用。
【解决方案3】:

我会用

import itertools
foo = [1, 5, 3, 6]
new = itertools.chain.from_iterable([item, item] for item in foo)

new 将是一个惰性迭代重复项的迭代器。如果您需要计算实际列表,您可以使用list(new) 或使用其他解决方案之一。

【讨论】:

  • 或更短:itertools.chain.from_iterable(itertools.izip(foo, foo))
  • 我认为该代码更短但对我来说似乎不太清晰。
【解决方案4】:

如果您已经拥有itertools 文档中描述的roundrobin 配方——而且非常方便——那么你可以使用

roundrobin(my_list, my_list)

【讨论】:

    【解决方案5】:

    尽管 Guido 不喜欢函数式运算符,但它们非常方便:

    >>> from operator import add
    >>> a = range(10)
    >>> b = reduce(add, [(x,x) for x in a])
    

    【讨论】:

    • 在reduce的情况下,方便通常意味着非常慢。衡量reduce 在做什么很重要。通常,令人震惊的是计算减少了多少力。
    • 我使用此页面上的每个方法制作了一个测试脚本,其中 baselist = range(10) 和 1,000,000 次迭代。最慢的耗时 5.094 秒,最快的耗时 3.622 秒。我的 reduce 示例耗时 3.906 秒。
    • range(10) 很小,因此复杂性的作用很小。这个解是二次的;我在这里看到的所有其他人都是线性的。此外,其他一些对我来说似乎更具可读性。
    【解决方案6】:

    我会使用zipitertools.chain

    >>> import itertools
    >>> l = [1,5,3,6,16]
    >>> list(itertools.chain(*zip(l,l)))
    [1, 1, 5, 5, 3, 3, 6, 6, 16, 16]
    

    注意:我只使用list 来消耗生成器以使其适合打印。您可能不需要在代码中调用 list...

    【讨论】:

      【解决方案7】:

      可以使用列表乘法。如果您需要每个列表成员一起使用,只需使用 sorted 方法。

      >>> lst = [1,2,3,4]
      >>> sorted(lst*2)
      [1,1,2,2,3,3,4,4]
      

      【讨论】:

      • 如果要保持原始列表的顺序呢?如果列表中的项目无法排序怎么办?
      • 排序输入的好解决方案。
      【解决方案8】:

      numpy.repeat 做你想做的事:

      import numpy as np
      yourList = [1,5,3,6]
      n = 2
      list(np.repeat(yourList, n))
      

      结果:

      [1, 1, 5, 5, 3, 3, 6, 6]
      

      如果您不介意使用 numpy 数组,也可以省略最后一行中的 list() 调用。

      【讨论】:

        【解决方案9】:

        稍微切片...

        >>> a = [3, 1, 4, 1, 5]
        >>> a[:0] = a[::2] = a[1::2] = a[:]
        >>> a
        [3, 3, 1, 1, 4, 4, 1, 1, 5, 5]
        

        【讨论】:

        • 它有效,但你能解释一下为什么吗?例如检查a[1::2] = a[:] 产生ValueError: attempt to assign sequence of size 5 to extended slice of size 2
        • 类似b=a*2; b[::2]=a; b[1::2]=a.
        • @Friedrich 目标被分配left to right,因此a[:0] 被首先分配,这将根据需要调整a 的大小以使以下两个分配工作。
        • 我在这里提供了这个 hack 的解释:stackoverflow.com/a/67241399/2111778
        【解决方案10】:

        可以使用 zip 和扁平化列表

        a = [3, 1, 4, 1, 5]
        sum(zip(a,a), ())   # (3, 3, 1, 1, 4, 4, 1, 1, 5, 5)
        

        输出是一个元组,但转换为列表很容易。 关于使用sum 扁平化元组,请参阅https://stackoverflow.com/a/952946/11769765python: flat zip

        【讨论】:

          【解决方案11】:

          对于更通用的方法,您可以使用列表理解和因子术语。

          示例

          sample_list = [1,2,3,4,5]
          factor = 2
          new_list = [entry for entry in sample_list for _ in range(factor)]
          

          输出:

          >>> new_list
          [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
          

          更改factor 变量将更改列表中每个项目的条目数,您将在新列表中拥有多少条目。

          您也可以将其包装在一个函数中:

          def multiply_list_entries(list_, factor = 1):
          
              list_multiplied = [entry for entry in list_ for _ in range(factor)]
              return list_multiplied
          
          >>> multiply_list_entries(sample_list, factor = 3)
          [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]
          

          【讨论】:

            【解决方案12】:
            ls1=[1,2,3]
            ls2=[]
            for i in ls1:
                ls2.append(i)
                ls2.append(i)
            

            这段代码复制了 ls1 中的每个元素 结果 ls2 --> [1,1,2,2,3,3]

            【讨论】:

            • 您能否解释一下您的答案,以便当有人遇到此问题时,他们也能理解它?谢谢!
            • 此答案被标记为低质量,请提供更多支持信息和解释以更好地回答或删除它
            猜你喜欢
            • 2016-06-30
            • 2020-11-05
            • 2013-10-20
            • 2013-12-27
            • 2010-12-26
            • 2014-04-07
            • 1970-01-01
            • 2013-03-21
            • 1970-01-01
            相关资源
            最近更新 更多