4 Aug 2012 08:58

## Recursive assignment in nested lists

```Is there a way to define a function which takes
a list (of lists),
a position specified by a list of integers [i0,i1,...,in], and
a value
and returns the result of setting
list[i0][i1]...[in]=value

The following function works for positions up to length 3 only.
Is it possible to write a general function that does this?

def setValueAtPosition(list,pos,value):
if len(pos)==1:
list[pos[0]]=value
elif len(pos)==2:
list[pos[0]][pos[1]]=value
elif len(pos)==3:
list[pos[0]][pos[1]][pos[2]]=value
return list

For example
>>> aa=[1,2,[3,4]]

>>> setValueAtPosition(aa,[2,0],5)
[1, 2, [5, 4]]

>>> aa
[1, 2, [5, 4]]

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
```
(Continue reading)

4 Aug 2012 09:20

### Re: Recursive assignment in nested lists

```On Sat, Aug 4, 2012 at 12:28 PM, Alonzo Quijote
<alonzo.quijote <at> gmail.com> wrote:
> Is there a way to define a function which takes
>    a list (of lists),
>    a position specified by a list of integers [i0,i1,...,in], and
>    a value
> and returns the result of setting
>     list[i0][i1]...[in]=value
>
> The following function works for positions up to length 3 only.
> Is it possible to write a general function that does this?
>
> def setValueAtPosition(list,pos,value):
>     if len(pos)==1:
>         list[pos[0]]=value
>     elif len(pos)==2:
>         list[pos[0]][pos[1]]=value
>     elif len(pos)==3:
>         list[pos[0]][pos[1]][pos[2]]=value
>     return list

Something like this, should work :

def setValueAtPosition(my_list, pos, value):
sub_list = my_list
for i in pos[:-1]:
sub_list = sub_list[i]
sub_list[pos[-1]] = value
return my_list

```
(Continue reading)

4 Aug 2012 09:27

### Re: Recursive assignment in nested lists

```On 04/08/12 16:58, Alonzo Quijote wrote:
> Is there a way to define a function which takes
>     a list (of lists),
>     a position specified by a list of integers [i0,i1,...,in], and
>     a value
> and returns the result of setting
>      list[i0][i1]...[in]=value

Yes it is possible, but if you need this, you should strongly consider
rearranging your data so it is easier to work with.

But, for what it's worth, try this:

def setValueAtPosition(list, pos, value):
tmp = list
for i in pos[:-1]:
tmp = tmp[i]
tmp[pos[-1]] = value

There's no need to return the list argument, because it changes it in-place.

And here is your example:

py> aa=[1, 2, [3, 4]]
py> setValueAtPosition(aa, [2, 0], 5)
py> aa
[1, 2, [5, 4]]

And a more complicated example:

```
(Continue reading)

4 Aug 2012 09:43

### Re: Recursive assignment in nested lists

```Alonzo Quijote wrote:

> Is there a way to define a function which takes
>    a list (of lists),
>    a position specified by a list of integers [i0,i1,...,in], and
>    a value
> and returns the result of setting
>     list[i0][i1]...[in]=value
>
> The following function works for positions up to length 3 only.
> Is it possible to write a general function that does this?
>
> def setValueAtPosition(list,pos,value):
>     if len(pos)==1:
>         list[pos[0]]=value
>     elif len(pos)==2:
>         list[pos[0]][pos[1]]=value
>     elif len(pos)==3:
>         list[pos[0]][pos[1]][pos[2]]=value
>     return list
>
> For example
>>>> aa=[1,2,[3,4]]
>
>>>> setValueAtPosition(aa,[2,0],5)
> [1, 2, [5, 4]]
>
>>>> aa
> [1, 2, [5, 4]]

```
(Continue reading)

4 Aug 2012 21:44

### Re: Recursive assignment in nested lists

```Thanks for all the help with this. I have 2 very quick follow-up questions:
---
1. Several responses proposed code like this:

def setValueAtPosition(list, pos, value):
tmp = list
for i in pos[:-1]:
tmp = tmp[i]
tmp[pos[-1]] = value

There must be a good reason that the responders use a tmp variable like this?
But I notice that the same effects can be obtained with:

def setValueAtPosition2(list, pos, value):
for i in pos[:-1]:
list = list[i]
list[pos[-1]] = value

Is there something wrong with this latter approach?
---
2. Another response observes that the function can be defined recursively like this:

def setValueAtPosition3(list, pos, value):
if len(pos) == 1:
list[pos[0]] = value
else:
inner_list = list[pos[0]]
new_pos = pos[1:]
setValueAtPosition3(inner_list, new_pos, value)

```
(Continue reading)

4 Aug 2012 22:48

### Re: Recursive assignment in nested lists

```On 04/08/12 20:44, Alonzo Quijote wrote:

> There must be a good reason that the responders use a tmp variable like this?
> But I notice that the same effects can be obtained with:
>
> def setValueAtPosition2(list, pos, value):
>       for i in pos[:-1]:
>           list = list[i]
>       list[pos[-1]] = value
>
> Is there something wrong with this latter approach?

Not for the specific case but the problem comes because you lost the
reference to the original list which is usually a bad idea, especially
if you decide you need to do anything with it.

> 2. Another response observes that the function can be defined recursively like this:
> Are the non-recursive solutions better?

Define "better".
Recursive functions in Python have a limit on the recursion depth so for
a very long list it will break. Recursion also tends to use more memory.

Use recursion where you have shallow data structures or very complex
structures which are themselves recursive - then rewrite it without
recursion, but only if necessary due to the above limitations.

--

--
Alan G
Author of the Learn to Program web site
```
(Continue reading)

4 Aug 2012 09:44

### Re: Recursive assignment in nested lists

```On Sat, Aug 4, 2012 at 12:28 PM, Alonzo Quijote
<alonzo.quijote <at> gmail.com> wrote:
> Is there a way to define a function which takes
>    a list (of lists),
>    a position specified by a list of integers [i0,i1,...,in], and
>    a value
> and returns the result of setting
>     list[i0][i1]...[in]=value
>
> The following function works for positions up to length 3 only.
> Is it possible to write a general function that does this?
>
> def setValueAtPosition(list,pos,value):
>     if len(pos)==1:
>         list[pos[0]]=value
>     elif len(pos)==2:
>         list[pos[0]][pos[1]]=value
>     elif len(pos)==3:
>         list[pos[0]][pos[1]][pos[2]]=value
>     return list
>
> For example
>>>> aa=[1,2,[3,4]]
>
>>>> setValueAtPosition(aa,[2,0],5)
> [1, 2, [5, 4]]
>
>>>> aa
> [1, 2, [5, 4]]
>
```
(Continue reading)

Gmane