Create list of single item repeated N times

前端 未结 6 1116
南笙
南笙 2020-11-22 03:57

I want to create a series of lists, all of varying lengths. Each list will contain the same element e, repeated n times (where n = len

相关标签:
6条回答
  • 2020-11-22 04:30

    You can also write:

    [e] * n
    

    You should note that if e is for example an empty list you get a list with n references to the same list, not n independent empty lists.

    Performance testing

    At first glance it seems that repeat is the fastest way to create a list with n identical elements:

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

    But wait - it's not a fair test...

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

    The function itertools.repeat doesn't actually create the list, it just creates an object that can be used to create a list if you wish! Let's try that again, but converting to a list:

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

    So if you want a list, use [e] * n. If you want to generate the elements lazily, use repeat.

    0 讨论(0)
  • 2020-11-22 04:36
    >>> [5] * 4
    [5, 5, 5, 5]
    

    Be careful when the item being repeated is a list. The list will not be cloned: all the elements will refer to the same list!

    >>> x=[5]
    >>> y=[x] * 4
    >>> y
    [[5], [5], [5], [5]]
    >>> y[0][0] = 6
    >>> y
    [[6], [6], [6], [6]]
    
    0 讨论(0)
  • 2020-11-22 04:45

    Itertools has a function just for that:

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

    Of course itertools gives you a iterator instead of a list. [e] * n gives you a list, but, depending on what you will do with those sequences, the itertools variant can be much more efficient.

    0 讨论(0)
  • 2020-11-22 04:47

    As others have pointed out, using the * operator for a mutable object duplicates references, so if you change one you change them all. If you want to create independent instances of a mutable object, your xrange syntax is the most Pythonic way to do this. If you are bothered by having a named variable that is never used, you can use the anonymous underscore variable.

    [e for _ in xrange(n)]
    
    0 讨论(0)
  • 2020-11-22 04:47
    [e] * n
    

    should work

    0 讨论(0)
  • 2020-11-22 04:51

    Create List of Single Item Repeated n Times in Python

    Immutable items

    For immutable items, like None, bools, ints, floats, strings, tuples, or frozensets, you can do it like this:

    [e] * 4
    

    Note that this is best only used with immutable items (strings, tuples, frozensets, ) in the list, because they all point to the same item in the same place in memory. I use this frequently when I have to build a table with a schema of all strings, so that I don't have to give a highly redundant one to one mapping.

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

    Mutable items

    I've used Python for a long time now, and I have never seen a use-case where I would do the above with a mutable instance. Instead, to get, say, a mutable empty list, set, or dict, you should do something like this:

    list_of_lists = [[] for _ in columns]
    

    The underscore is simply a throwaway variable name in this context.

    If you only have the number, that would be:

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

    The _ is not really special, but your coding environment style checker will probably complain if you don't intend to use the variable and use any other name.


    Caveats for using the immutable method with mutable items:

    Beware doing this with mutable objects, when you change one of them, they all change because they're all the same object:

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

    foo now returns:

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

    But with immutable objects, you can make it work because you change the reference, not the object:

    >>> 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([])]
    

    But again, mutable objects are no good for this, because in-place operations change the object, not the reference:

    l = [set()] * 4
    >>> l[0] |= set('abc')    
    >>> l
    [set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b'])]
    
    0 讨论(0)
提交回复
热议问题