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.
Related
Let's say I have accessed my dictionary keys using print (hamdict.keys())
Below is a sample output:
I know my dictionary list has a length of 552 elements. I want to randomly select one "key" word from my list and assign it to the variable "starter". I tried to do this with the code below (note: I have a dictionary called hamdict):
random_num = random.randint(0, len(hamdict.keys())-1)
print (random_num)
print (hamdict.keys()[random_num])
I'm able to get a value for random_num so that seems to work. But the second print returns the following error:
How can I fix my code?
my_dictionary.keys() returns a generator-like object, not a list. You can probably get what you want by converting it to a list first
print(list(hamdict.keys())[random_num])
Try this:
random.sample(hamdict.keys(),1)[0]
The sample() function randomly selects a given number of items from a list or iterator. Contrary to the choice function, it supports iterators so you don't need to make a list out of the keys beforehand. The result is a list so you need to get its first item from the output (hence the [0]).
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:]
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.
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]
I have a list of several thousand unordered tuples that are of the format
(mainValue, (value, value, value, value))
Given a main value (which may or may not be present), is there a 'nice' way, other than iterating through every item looking and incrementing a value, where I can produce a list of indexes of tuples that match like this:
index = 0;
for destEntry in destList:
if destEntry[0] == sourceMatch:
destMatches.append(index)
index = index + 1
So I can compare the sub values against another set, and remove the best match from the list if necessary.
This works fine, but just seems like python would have a better way!
Edit:
As per the question, when writing the original question, I realised that I could use a dictionary instead of the first value (in fact this list is within another dictionary), but after removing the question, I still wanted to know how to do it as a tuple.
With list comprehension your for loop can be reduced to this expression:
destMatches = [i for i,destEntry in enumerate(destList) if destEntry[0] == sourceMatch]
You can also use filter()1 built in function to filter your data:
destMatches = filter(lambda destEntry:destEntry[0] == sourceMatch, destList)
1: In Python 3 filter is a class and returns a filter object.