On Thu, Nov 8, 2012 at 1:26 AM, Andrew Robinson <andr...@r3dsolutions.com> wrote: > OK: Then copy by reference using map....: > > values = zip( map( lambda:times, xrange(num_groups) ) ) > if len(values) < len(times) * num_groups ... > > Done. It's clearer than a list comprehension and you still really don't > need a list multiply.
That is not equivalent to the original. Even had you not omitted some parts: values = zip(samples, map(lambda i: times, range(num_groups))) This still has the problem that map returns a list of num_groups elements, each of which is times. The desired value to be passed into zip is a *single* sequence containing len(times) * num_groups elements. This is easily handled by list multiplication, but not so easily by map or by a single list comprehension. Looking back at the 'ini' solution you proposed before, I see that this also would be a problem there. Fixing the above, it would have to be something like: values = zip(samples, reduce(operator.add, map(lambda i: times, range(num_groups)), [])) Or from how I understand the 'ini' syntax to work: values = zip(samples, reduce(operator.add, [lambda: times, ini xrange(num_groups)], [])) Which brings to mind another point that I want to get to in a moment. But when I said that I would use map instead, I meant that *if* the body of the list comprehension is just a function application, then I would prefer to use map over the list comprehension. But in the above I see no benefit in using a lambda in the first place. Getting back to that other point, notice what we ended up doing in both of those constructions above: repeated list concatenation as a substitute for multiplication. In fact, when we multiply (aList * 5), this should be the equivalent of (aList + aList + aList + aList +aList), should it not? Clearly, however, there should be no implicit copying involved in mere list concatenation. For one thing, if the user wants to concatenate copies, that is quite easily done explicitly: (aList[:] + aList[:]) instead of (aList + aList). For another, list concatenation is less likely to be used for an initialization process. If list multiplication were to copy nested lists, then, this would break the intuitive notion that list multiplication is equivalent to repeated list concatenation. > Yes, but you're very blind to history and code examples implementing the > slice operation. > slice usually depends on index; index does not depend on slice. > Slice is suggested to be implemented by multiple calls to single indexes in > traditional usage and documentation. ...and then by composing the elements located at those indexes into a subsequence. > The xrange(,,)[:] implementation breaks the tradition, because it doesn't > call index multiple times; nor does it return a result equivalent identical > to doing that. Whether any given __getitem__ slicing implementation recursively calls __getitem__ with a series of indexes or not is an implementation detail. If it were possible to index a range object multiple times and then stuff the results into another range object, then the slicing result would be equivalent. The only reason it is not is that you cannot construct a range object in that fashion. I think that what you're expecting is that range(5)[:] should return a list in Python 3 because it returns a list in Python 2. This does not represent a change in slicing behavior -- in fact, all you got by slicing an xrange object in Python 2 was a TypeError. This represents an intentional break in backward compatibility between Python 2 and Python 3, which was the purpose of Python 3 -- to fix a lot of existing warts in Python by breaking them all at once, rather than progressively over a long string of versions. Users porting their scripts from Python 2 to Python 3 are advised to replace "range(...)" with "list(range(...))" if what they actually want is a list, and I believe the 2to3 tool does this automatically. Once the range object is converted to a list, there is no further break with Python 2 -- slicing a list gives you a list, just as it always has. In a nutshell, yes: range(...)[:] produces a different result in Python 3 than in Python 2, just as it does without the slicing operation tacked on. It was never intended that scripts written for Python 2 should be able to run in Python 3 unchanged without careful attention to detail. -- http://mail.python.org/mailman/listinfo/python-list