代码之家  ›  专栏  ›  技术社区  ›  chimeracoder

在Python中创建重复n次的单个项的列表

  •  405
  • chimeracoder  · 技术社区  · 16 年前

    我想创建一系列不同长度的列表。每个列表将包含相同的元素 e ,重复 n

    如何创建列表,而不使用列表理解 [e for number in xrange(n)] 对于每个列表?

    6 回复  |  直到 6 年前
        1
  •  884
  •   Mark Byers    16 年前

    你也可以写:

    [e] * n
    

    您应该注意,如果e是一个空列表,那么您将得到一个包含n个对同一列表的引用的列表,而不是n个独立的空列表。

    性能测试

    乍一看是这样

    >>> timeit.timeit('itertools.repeat(0, 10)', 'import itertools', number = 1000000)
    0.37095273281943264
    >>> timeit.timeit('[0] * 10', 'import itertools', number = 1000000)
    0.5577236771712819
    

    但是等等-这不是一个公平的测试。。。

    >>> itertools.repeat(0, 10)
    repeat(0, 10)  # Not a list!!!
    

    函数 itertools.repeat

    >>> timeit.timeit('list(itertools.repeat(0, 10))', 'import itertools', number = 1000000)
    1.7508119747063233
    

    所以如果你想要一个列表,使用 [e] * n repeat .

        2
  •  170
  •   viebel    14 年前
    >>> [5] * 4
    [5, 5, 5, 5]
    

    当重复的项目是一个列表时要小心。列表将不会被克隆:所有元素将引用同一个列表!

    >>> x=[5]
    >>> y=[x] * 4
    >>> y
    [[5], [5], [5], [5]]
    >>> y[0][0] = 6
    >>> y
    [[6], [6], [6], [6]]
    
        3
  •  96
  •   Aaron Hall    5 年前

    在Python中创建重复n次的单个项的列表

    根据您的用例,您需要使用具有不同语义的不同技术。

    将不可变项的列表相乘

    对于不可变项,如None、bools、int、float、strings、tuples或frozenset,您可以这样做:

    [e] * 4
    

    schema = ['string'] * len(columns)
    

    将我们想要重复相同项目的列表相乘

    将列表相乘得到 相同的

    [iter(iterable)] * 4
    

    这有时用于将iterable映射到列表列表:

    >>> iterable = range(12)
    >>> a_list = [iter(iterable)] * 4
    >>> [[next(l) for l in a_list] for i in range(3)]
    [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
    

    a_list

    >>> a_list
    [<range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>]
    

    可变项

    我已经使用Python很长一段时间了,我很少看到使用可变对象执行上述操作的用例。

    list_of_lists = [[] for _ in columns]
    

    下划线在此上下文中只是一个一次性变量名。

    list_of_lists = [[] for _ in range(4)]
    

    _ 不是很特别,但是如果您不打算使用变量和任何其他名称,那么您的编码环境样式检查器可能会抱怨。


    对可变项使用不可变方法的注意事项:

    小心使用可变对象 ,当你改变其中一个时,它们都会改变,因为它们都是 相同的

    foo = [[]] * 4
    foo[0].append('x')
    

    foo现在返回:

    [['x'], ['x'], ['x'], ['x']]
    

    >>> l = [0] * 4
    >>> l[0] += 1
    >>> l
    [1, 0, 0, 0]
    
    >>> l = [frozenset()] * 4
    >>> l[0] |= set('abc')
    >>> l
    [frozenset(['a', 'c', 'b']), frozenset([]), frozenset([]), frozenset([])]
    

    但同样,可变对象对此也没有好处,因为就地操作更改的是对象,而不是引用:

    l = [set()] * 4
    >>> l[0] |= set('abc')    
    >>> l
    [set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b'])]
    
        4
  •  27
  •   Mad Physicist    9 年前

    Itertools有一个功能:

    import itertools
    it = itertools.repeat(e,n)
    

    itertools 给你一个迭代器而不是一个列表。 [e] * n 给你一个列表,但是,取决于你将如何处理这些序列 itertools公司 变种可以更有效。

        5
  •  15
  •   W.P. McNeill    11 年前

    正如其他人所指出的,对可变对象使用*运算符会复制引用,因此如果更改一个对象,则会更改所有引用。如果您想创建一个可变对象的独立实例,那么xrange语法是最适合的方法。如果您对从未使用过的命名变量感到烦恼,可以使用匿名下划线变量。

    [e for _ in xrange(n)]
    
        6
  •  12
  •   Mad Scientist    16 年前
    [e] * n
    

    应该有用

        7
  •  -2
  •   Shrm    5 年前

    [1, 2, 3, 1, 2, 3, 1, 2, 3]
    

    简单使用:

    [1, 2, 3] * 3
    

    [1, 1, 1, 2, 2, 2, 3, 3, 3]
    

    这一个更好,但需要更多的时间:

    numpy.concatenate([([i]*3) for i in [1,2,3]], axis=0)