List replication operator

Rob Gaddi rgaddi at highlandtechnology.invalid
Fri May 25 13:41:08 EDT 2018


On 05/25/2018 10:13 AM, bartc wrote:
> On 25/05/2018 17:58, Rob Gaddi wrote:
>>> So, in the spirit of explicit being better than implicit, please 
>> assume that for actual implementation replicate would be a static 
>> method of actual list, rather than the conveniently executable hackjob 
>> below.
>>>> _list = list
>> _nodefault = object()
>>>> class list(_list):
>>    @staticmethod
>>    def replicate(*n, fill=_nodefault, call=list):
>> That seems to work, but the dimensions are created in reverse order to 
> what I expected. Which is to have the order of indices corresponding to 
> the order of dimensions. So:
>>  x=list.replicate(2,3,4)
>>  print (len(x))
>  print (len(x[0]))
>  print (len(x[0][0]))
>> Gives output of 4, 3, 2 rather than 2, 3, 4.
>> Which means that x[0][0][3] is a bounds error.
>
A fair point. Something about multidimensional arrays always makes me 
semi-dyslexic. And there I was wondering why making it work right had 
required I rip dimensions off the list from the end instead.
Corrected version below. list.replicate(3, 2) now means "3 of 2 of 
this" as one would expect. This is one of those days when doctest is my 
favorite thing about Python.
_list = list
_nodefault = object()
class list(_list):
 @staticmethod
 def replicate(*n, fill=_nodefault, call=list):
 """Return a list of specified dimensions.
 Fill and call can be used to prime the list with initial values, the
 default is to create a list of empty lists.
 Parameters:
 n : List of dimensions
 fill: If provided, the fill object is used in all locations.
 call: If fill is not provided, the result of call (a function of
 no arguments) is used in all locations.
 Example:
 >>> a = list.replicate(3, 2)
 >>> a
 [[[], []], [[], []], [[], []]]
 >>> a[0][0].append('a')
 >>> a
 [[['a'], []], [[], []], [[], []]]
 >>> b = list.replicate(3, 2, fill=[])
 >>> b
 [[[], []], [[], []], [[], []]]
 >>> b[0][0].append('a')
 >>> b
 [[['a'], ['a']], [['a'], ['a']], [['a'], ['a']]]
 >>> c = list.replicate(3, 2, call=dict)
 >>> c
 [[{}, {}], [{}, {}], [{}, {}]]
 >>> c[0][0]['swallow'] = 'unladen'
 >>> c
 [[{'swallow': 'unladen'}, {}], [{}, {}], [{}, {}]]
 >>> d = list.replicate(3, 2, fill=0)
 >>> d
 [[0, 0], [0, 0], [0, 0]]
 >>> d[0][0] = 5
 >>> d
 [[5, 0], [0, 0], [0, 0]]
 """
 if n:
 this = n[0]
 future = n[1:]
 return [
 list.replicate(*future, fill=fill, call=call)
 for _ in range(this)
 ]
 elif fill is _nodefault:
 return call()
 else:
 return fill
-- 
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /