Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appending item to lists within a list comprehension

I have a list, let's say, a = [[1,2],[3,4],[5,6]]

I want to add the string 'a' to each item in the list a.

When I use:

a = [x.append('a') for x in a]  

it returns [None,None,None].

But if I use:

a1 = [x.append('a') for x in a] 

then it does something odd.

a, but not a1 is [[1,2,'a'],[3,4,'a'],[5,6,'a']].

I don't understand why the first call returns [None, None, None] nor why the second changes on a instead of a1.

like image 412
ariel Avatar asked Mar 24 '10 05:03

ariel


People also ask

Can you append in list comprehension?

append() into a list comprehension, you just need to put its argument followed by the loop header (without the colon) inside a pair of square brackets.

Can you append a list to a list?

append() adds a list inside of a list. Lists are objects, and when you use . append() to add another list into a list, the new items will be added as a single object (item).

How do you append the contents of a list to another list?

To append a list to another list, use extend() function on the list you want to extend and pass the other list as argument to extend() function. In this tutorial, we shall learn the syntax of extend() function and how to use this function to append a list to other list.

How do I add elements to a list in Python list comprehension?

Append method is used to append elements. This adds the element to the end of the list. Looping method of Python program can be performed on multiple elements of a data list at the same time.


2 Answers

list.append mutates the list itself and returns None. List comprehensions are for storing the result, which isn't what you want in this case if you want to just change the original lists.

>>> x = [[1, 2], [3, 4], [5, 6]] >>> for sublist in x: ...     sublist.append('a') ... >>> x [[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']] 
like image 87
Mike Graham Avatar answered Sep 23 '22 15:09

Mike Graham


As others have said, append mutates the list itself and you shouldn't assign it to a variable. Executing it changes it's data, effectively updating everyone pointing at it.

But, there's a trick I use when I want to do stuff in a functional* way while mutating existing objects (rather than constructing new ones, in this case using a=[x + ['a'] for x in a], or specifically the x + ['a']).

So, if you're brave enough you can also do this:

>>> a=[[1,2],[3,4],[5,6]] >>> a=[x.append('a') or x for x in a] >>> a [[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']] 

This works because append returns None, and the or continues on to search for a truth-y value, which x is (it's a list with at least what was appended to it).

Why do I even need this?

Say you have a list and you want to insert some of it's members to a new list, and update the references accordingly:

So you have the list all:

>>> all = [[], [], [], []] 

Some of it is inserted and updated to a new list x:

>>> x = [i.append('x') or i for i in all[:2]] >>> x [['x'], ['x']] 

Some of all is also inserted and updated to a list y:

>>> y = [i.append('y') or i for i in all[1:3]] 

all is updated:

>>> all [['x'], ['x', 'y'], ['y'], []] 

But x is also updated:

>>> x [['x'], ['x', 'y']] 

And y is generated as expected:

>>> y [['x', 'y'], ['y']] 

Overall, for simple tasks, I'd recommend using a for loop updating explicitly. This is what's considered pythonic.

Technically speaking, if you had access to the list class, you could make this a function:

def more_functional_append(self, x):     self.append(x)     return self 
  • functional programming is based on every statement doing essentially one thing, and not having side effects (so, not mutating and returning). append is not very functional since it mutates a list (pure functional programming has only immutable objects) and does not return a result to pass to other actions (functions). Using functional programming concepts you can create great big one-liners no one can read, also known as "job security" or "bad code".
like image 44
Reut Sharabani Avatar answered Sep 25 '22 15:09

Reut Sharabani