
And like I said before, for loop is just another way of doing while loop, yet nobody's complaining. There's nothing wrong with having two different ways of doing the same thing, as long as one of them is never the better way. If we add `repeat`, there's never a reason to use `for _ in range` anymore. What comes to your custom class solution, it's uglier, harder to follow, and way slower than just doing: d = [[0]*5 for _ in range(10)] While the proposed method would be faster, shorter, and cleaner. And like I said many times, the matrix example is just one of many. On Mar 30, 2017 19:54, "Joao S. O. Bueno" <jsbueno@python.org.br> wrote:
On 30 March 2017 at 13:10, Markus Meskanen <markusmeskanen@gmail.com> wrote:
On Mar 30, 2017 19:04, "Joao S. O. Bueno" <jsbueno@python.org.br> wrote:
On 30 March 2017 at 10:51, Mark E. Haase <mehaase@gmail.com> wrote:
Your example is really repeating two things:
d = [ [0 for _ in range(5)] for _ in range(10) ]
But since list() uses * for repetition, you could write it more
concisely
as:
d = [[0] * 5] * 10]
I'm not picking on your specific example. I am only pointing out that Python gives you the tools you need to build nice APIs. If repetition is an important part of something you're working on, then consider using itertools.repeat, writing your own domain-specific repeat() method, or even override * like list() does. One of the coolest aspects of Python is how a relatively small set of abstractions can be combined to create lots of useful behaviors.
I find it weird that not the author, neither the previous repliers noticed that "a repetition other than a for with dummy variable" was already in plain sight, in the very example given. Of course one is also free to write [ [0 for _ in range(5)] for _ in range(10)] if he wishes so.
Had you read all the replies, you'd see people (including me, OP) repeating this multiple times:
d = [[0] * 5] * 10
Creates a list of ten references *to the same list*. This means that if I mutate any of the sub lists in d, all of the sub lists get mutated. There would only be one sub list, just ten references to it.
Yes. Nonetheless, it is still repeating. Accepting a new way for doing this would go from 2 ways with 2 semantics to 3 ways with two different semantics.
And, all you need is to create a special class to actually dupicate the list on multiplying - not a big deal:
In [76]: class D: ...: def __init__(self, value): ...: self.value = value ...: def __rmul__(self, other): ...: if hasattr(other, '__len__') and hasattr(other, '__add__'): ...: result = deepcopy(other) ...: for _ in range(1, self.value): ...: result += deepcopy(other) ...: return result ...: return NotImplemented ...:
In [77]: from copy import deepcopy
In [78]: a = [[0] * 5] * D(10)
In [79]: a[5][2] = "*"
In [80]: a Out[80]: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, '*', 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]