Append select dict keys to a list [duplicate] - python

I am trying to append objects to the end of a list repeatedly, like so:
list1 = []
n = 3
for i in range(0, n):
list1 = list1.append([i])
But I get an error like: AttributeError: 'NoneType' object has no attribute 'append'. Is this because list1 starts off as an empty list? How do I fix this error?
This question is specifically about how to fix the problem and append to the list correctly. In the original code, the reported error occurs when using a loop because .append returns None the first time. For why None is returned (the underlying design decision), see Why do these list operations return None, rather than the resulting list?.
If you have an IndexError from trying to assign to an index just past the end of a list - that doesn't work; you need the .append method instead. For more information, see Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add elements to a list?.
If you want to append the same value multiple times, see Python: Append item to list N times.

append actually changes the list. Also, it takes an item, not a list. Hence, all you need is
for i in range(n):
list1.append(i)
(By the way, note that you can use range(n), in this case.)
I assume your actual use is more complicated, but you may be able to use a list comprehension, which is more pythonic for this:
list1 = [i for i in range(n)]
Or, in this case, in Python 2.x range(n) in fact creates the list that you want already, although in Python 3.x, you need list(range(n)).

You don't need the assignment operator. append returns None.

append returns None, so at the second iteration you are calling method append of NoneType. Just remove the assignment:
for i in range(0, n):
list1.append([i])

Mikola has the right answer but a little more explanation. It will run the first time, but because append returns None, after the first iteration of the for loop, your assignment will cause list1 to equal None and therefore the error is thrown on the second iteration.

I personally prefer the + operator than append:
for i in range(0, n):
list1 += [[i]]
But this is creating a new list every time, so might not be the best if performance is critical.

Note that you also can use insert in order to put number into the required position within list:
initList = [1,2,3,4,5]
initList.insert(2, 10) # insert(pos, val) => initList = [1,2,10,3,4,5]
And also note that in python you can always get a list length using method len()

Like Mikola said, append() returns a void, so every iteration you're setting list1 to a nonetype because append is returning a nonetype. On the next iteration, list1 is null so you're trying to call the append method of a null. Nulls don't have methods, hence your error.

use my_list.append(...)
and do not use and other list to append as list are mutable.

Related

Python List Append not working on sliced lists

I have a list a = [1,2,3,4,5]
I don't understand why the following code doesn't produce [2,3,4,5,1]
a[1:].append(a[0])
I tried reading up on the append() method as well as list slicing in Python, but found no satisfactory response.
a[1:] gives you a whole new list, but you're not assigning it to any variable so it it just thrown away after that line. You should assign it to something (say, b) and then append to it (otherwise append would change the list but return nothing):
a = [1,2,3,4,5]
b = a[1:]
b.append(a[0])
And now b is your desired output [2,3,4,5,1]
I think here you just not really understand append function. Just like my answer in Passing a variable from one file into another as a class variable after inline modification, append is an in-place operation which just update the original list and return None.
Your chain call a[1:].append(a[0]) will return the last call return value in the chain, so return append function value, which is None.
Just like #flakes comment in another answer, a[1:] + a[:1] will return your target value. Also you can try a[1:][1:][1:] which will return some
result. So the key point is the append function is in-place function.
See python more on list
You might have noticed that methods like insert, remove or sort that only modify the list have no return value printed – they return the default None. 1 This is a design principle for all mutable data structures in Python.
First, append the first element a[0] to the list
a.append(a[0])
and then exclude the first element
a[1:]

Outputting None instead of Values

I am trying to utilize list comprehension to populate a new list, which is the length of text in a DataFrame column.
So if the text is "electrical engineer", it should output 19 etc. Instead, it just fills the list with None values
I have written out list comprehension below
all_text_length = [all_text_length.append(len(i)) for i in data['all_text']]
Expecting output of integer but its None
As a workaround, I am currently using (successfully)
[all_text_length.append(len(i)) for i in data['all_text']]```
Read the documentation on append: it works in-place. There is no returned value. What you've written is essentially
all_text_length = [None for i in data['all_text']]
It appears that you're trying to make a list comprehension to entirely change your list. Try this:
all_text_length = [len(i) for i in data['all_text']]
If you just need the lengths in a convenient form, would it do to form a new column? Simply apply len to the df column.
The value before the "for" statement in the list comprehension, will be added to the list. If you place a statement in there, like
all_text_length.append(len(i)
, the return value of that function will be added. Because .append() doesnt have areturn-statement in it, you get the value None as return type, wich will be added to your list.
Use the code #Prune recommended and it should work as you want.
You are trying to append to the same list on which you are doing list comprehension. Since the append returns a None type, you are getting None. The below code should work,
all_text_length = map(len, data['all_text'])
map is a function that takes another function (first argument) and applies it to every element in an iterable (second argument) and returns a list of the results.

How do I add an element inside a list which is inside a list?

l = [1,2,3,[4,5,6]]
I want
l = [1,2,3,[4,5,6,7]]
Now I want to add 7 in the list which is inside the list.
I applied the same logic as accessing [3][3]
l.insert("index","value") #syntax
l.insert([3][3],7)
But it isn't working. I couldn't solve it with append as well.
You want to add a 7 to the element at index 3 in l.
That is:
l[3].append(7)
you can do the following:
l[3].insert(3,7)
What's wrong with your approach? In the insert(index, value) method the index should be an integer. The [3][3] you are passing, is not an integer. Moreover, it is not even a valid value (meaning, you can't write eg x = [3][3].
The [i] after an object calls its __getitem__ method internally. So, what you are trying to do is
get the element 3 of the initial list
hope that what you get is a list
insert on position 3 of that list
So, you can do that
inner_list = mylist[3]
inner_list.insert(3, 7)
or, more compactly mylist[3].insert(3, 7)
If you want to insert at the last position, you could as well write mylist[3].append(7)
Here l[3][3] is an int. Ofcouse it will not work as there are no built-ins defined such as insert and append on int
While l[3] is of list type so it supports both of those functions
l[3].append(7) or l[3].insert(3,7)
Also lists are mutable type so making a change in inner list will be reflected in the outer list as well. Hope it helps
you can access to that 7 with:
l[3][3]

Initialize a list using inline for loop

I am initializing my list object using following code.
list = [
func1(centroids[0],value),
func1(centroids[1],value),
....,
func1(centroids[n],value)]
I am trying to do it a more elegant way using some inline iteration. Following is the pseudo code of one possible way.
list = [value for value in func1(centroids[n],value)]
I am not clear how to call func1 in an iterative way. Can you suggest a possible implementation?
For a list of objects, Python knows how to iterate over it directly so you can eliminate the index shown in most of the other answers,
res = [func1(c, value) for c in centroids]
That's all there is to it.
A simple list comprehension consists of the "template" list element, followed by the iterator needed to step through the desired values.
my_list = [func1(centroids[0],value)
for n in range(n+1)]
Use this code:
list = [func1(centroids[x], value) for x in range(n)]
This is called a list comprehension. Put the values that you want the list to contain up front, then followed by the for loop. You can use the iterating variable of the for loop with the value. In this code, you set up n number(s) of variable(s) from the function call func1(centroids[x], value). If the variable n equals to, let's say, 4, list = [func1(centroids[0], value), func1(centroids[0], value), func1(centroids[0], value), func1(centroids[0], value)] would be equal to the code above

Incrementing index for list.append()

I have a list of 100 URLs in a list called recipe_urls and I am trying to remove the the first 37 characters from each element in that list and store it in a new list called recipe_names. How can I increment the index position in .insert(). Maybe I am thinking about this wrong and there is an easier way to do this?
recipe_names = []
for url in recipe_urls:
recipe_names.insert(x, url[37:0])
This is all you need:
recipe_names = [x[37:] for x in recipe_urls]
This method of building a list from another iterable or sequence is called list comprehension
Since you always want it to go at the end of recipe_names, you can use the index -1, or even just call append instead (which doesn't take an index, and always puts the new value at the end of the list). But whenever you have code that creates an empty list, then iterates over something else to append to that new list, you can use a list comprehension instead:
recipe_names = [url[37:] for url in recipe_urls]

Categories

Resources