Python List Append not working on sliced lists - python

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:]

Related

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]

Append select dict keys to a list [duplicate]

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.

Is it possible to use an append function in a return statement for purposes of a recursive procedure in Python

Is it possible to use an append function in a return statement?
If I say:
def test_func(n):
a=[1,2,3]
a.append(n)
return a
print test_func(6)
I get:
[1,2,3,6]
But if I say:
def test_func(n):
a=[1,2,3]
return a.append(n)
print test_func(6)
I get:
None
The reason I want this is because I want to write a recursive function that calls itself until the base case is reached, but for each cycle it executes, I want to append that result to a list.
So I want to try something along the lines of: return a.append(func(new_input))
Basically, am I doing something wrong in the above example? Or is it not possible to append in the return statement.
You can replace append by a call to __iadd__:
def test_func(n):
a = [1, 2, 3]
return a.__iadd__([n])
This should work.
But I don't understand why you don't use your first idea.
The append function does not return any value but updates the existing list.
In your first implementation you are returning the list a, in your second implementation you are returning the return value of the function append (that always return None).
So, the answer is: it is not possible the function append be in the return statement and works the way you want.

Python, change value of the arguments within the function

I'm trying to change the value of the list that i put as argument in the function.
this is the code:
def shuffle(xs,n=1):
if xs: #if list isn't empty
if n>0:
#gets the index of the middle of the list
sizel=len(xs)
midindex=int((sizel-1)/2)
for times in range(n):
xs=interleave(xs[0:midindex],xs[midindex:sizel])
return None
The interleave code returns a list with the values of both lists mixed up.
However when i run:
t=[1,2,3,4,5,6,7]
shuffle(t,n=2)
print t
The list t didn't changed it's order. The function needs to return None so i can jst use t=shuffle(t,n). There's anyway i can do this?
Your problem is right here:
xs=interleave(xs[0:midindex],xs[midindex:sizel])
You're making slices of the list to pass to your interleave() function. These are essentially copies of part of the list. There's no way that what comes back from the function can be anything than a different list from xs.
Fortunately, you can just reassign the new list you get back into the original list. That is, keep xs pointing to the same list, but replace all the items in it with what you get back from the interleave() function.
xs[:]=interleave(xs[0:midindex],xs[midindex:sizel])
This is called a slice assignment. Since xs remains the same list that was passed in, all references to the list outside the function will also see the changes.
xs is a reference local to the function, and is independant of t. When you reassign xs, t still points to the original list.
Since you must not return anything from the function, a workaround is to keep a reference to the original list and repopulate it using slice assignment:
orig_xs = xs
# do stuff here
orig_xs[:] = xs

Categories

Resources