Skip to content Skip to sidebar Skip to footer

What Are These Python Notations: `[ [] ] * N` And `(i,)`

Can someone please clarify these 2 notations in Python: [ [] ] * n: apparently this creates n references to the same object (in this case, an empty list). In which situations is t

Solution 1:

Yes, that does create references to the same object:

>>> L = [[]] * 3
>>> L
[[], [], []]
>>> L[0].append(1)
>>> L
[[1], [1], [1]]
>>> map(id, L)
[4299803320, 4299803320, 4299803320]

This could be useful for whenever you want to create objects with the same items.


(i,) creates a tuple with the item i:

>>>mytuple = (5,)>>>print mytuple
(5,)
>>>printtype(mytuple)
<type 'tuple'>

The reason the comma is needed is because otherwise it would be treated as an integer:

>>>mytuple = (5)>>>print mytuple
5
>>>printtype(mytuple)
<type 'int'>

Solution 2:

[ [] ] * n creates n references to the same empty list object. This is almost always a bug, since usually you'll end up using a destructive operation on one of the n lists and then being surprised when it applies to "all" of the elements of your outer list.

However [0] * n creates n references to the same integer-zero object. Expressions like this can be handy for initializing a list of counters (you would presumably then go on to replace individual slots in the list). Since integers are immutable, there is no danger of altering "all" of the zeroes accidentally. The same goes for any other "immutable all the way down" type (not necessarily tuples, since although the tuple itself is immutable it can contain mutable values).

So this "list multiplication" operation isn't useless. But I would advise avoiding it except for the specific case of replicating a list of guaranteed immutable values. While multiplying a list of mutable values can be used safely, it's so fragile and so often the root cause of a bug that even when that is what you mean to do you're better of doing it in a slightly more verbose way that makes it obvious you really mean it.


As for (i,), Python allows an "extra" comma in list, dictionary, tuple, and set literals. For example, the following are all valid:

(1, 2, 3,)
[1, 2, 3,]
{1: 'one', 2: 'two', 3: 'three',}
{1, 2, 3,}

This doesn't do anything different than if you'd left out the trailing comma, it's simply allowed as optional extra.

Back to (i,). This is simply a tuple of one item with the trailing comma. But there's a catch; for the special case of tuples with only one item the trailing comma isn't an optional extra, it's mandatory. That's because a "one-tuple" would otherwise be written (i), but that syntactic form is already taken for using parentheses to group a sub-expression (e.g. you couldn't otherwise tell whether (1 + 1) * 2 was supposed to produce 4 or (2, 2)).


As an aside, the reason why you might want to use the optional trailing comma sometimes is more obvious when you're splitting a long tuple/list/dictionary/set over multiple lines:

foo = [
   'this',
   'is',
   'a',
   'long',
   'list',
]

Writing in this style allows me to re-order the list simply by re-ordering the source code lines; I don't have to then go and clean up the commas if one of the items I re-ordered was the last one in the list.

Similarly if I'm using version control, adding more items after the last one doesn't change the line with the previously-final item, so the diff is a pure addition. If the last line didn't have a comma you would need to add one to add more items, which makes the change recorded as an edit to that line, which makes merge conflicts (slightly) more likely and history logs (slightly) harder to read.

Solution 3:

[[]] * n creates references to the same mutable list. Lots of times this is not what is needed and instead you need unique list objects that can be modified separately. To do that you can use this:

list_of_lists = [[] for i in xrange(n)]

Solution 4:

By far, the most common use of [...] * n must be the grouper recipe

defgrouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

Post a Comment for "What Are These Python Notations: `[ [] ] * N` And `(i,)`"