This question already has answers here:
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 1 year ago.
I have a question about list compressions within Python.
I am learning through Udacity and uploading my answers/code to an IDE (I could be wrong about it being an IDE) they have through my browser.
Before uploading I like to test my code to see if it actually works...as of now I am using Windows Powershell. So the code below is run on Powershell. But my question is...why when I run my code does it print [None, None, None, None] but when I print(new_list) I get ['a','b','c','d']
letters = ['A', 'B', 'C', 'D']
[new_list.append(letter.lower()) for letter in letters]
print(new_list)
When I upload the code to the browser I get a 'Nonetype' object is not an iterable. Makes sense... considering Powershell tells me it is initially viewed as a Nonetype. But, why?
You are almost there. It should be:
letters = ['A', 'B', 'C', 'D']
new_list = [letter.lower() for letter in letters]
print(new_list)
E.g. have a look here for comparison of list comprehension vs for loop.
The above code snippet with a list comprehension equals to:
letters = ['A', 'B', 'C', 'D']
new_list = list()
for letter in letters:
new_list.append(letter.lower())
print(new_list)
You should be doing something like this:
letters = ['A', 'B', 'C', 'D']
new_list = [letter.lower() for letter in letters]
print(new_list)
The error comes from this line:
[new_list.append(letter.lower()) for letter in letters]
On new_list.append(...) you have not declared the new_list array variable (it doesn't exist), and you're telling it to append something to it.
List comprehensions are a replacement for creating a new list and then appending to it. You create it and populate it in one go
Related
Suppose that I am given a list of strings, e.g. list = ['a', 'b', 'c']. I am also given a list of 'continuation strings', e.g. continuations = ['d', 'f'], and I want to form a list of all possible sequences formed by combining the original list with a continuation letter. In this example, I want to obtain the list of lists: new_list = [['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'f']]. To do this, I tried
new_list = []
for element in continuations:
# Make a copy of the original list
copy = list
# Add a continuation letter to the original list
possible_sequence = copy.append(element)
# Add the new list to the list of lists
new_list.append(possible_sequence)
But this generates [None, None]... Can anyone explain what is wrong with my code?
# it is a bad practice to shadows built-in name, so I changed 'list' name to 'abc_list'
abc_list = ['a', 'b', 'c']
continuation = ['d', 'f']
print([abc_list + [x] for x in continuation])
Output: [['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'f']]
CODE
main_list = ['a', 'b', 'c']
continuations = ['d', 'f']
new_list = []
for element in continuations:
temp_list = main_list.copy()
temp_list.append(element)
new_list.append(temp_list)
print(new_list)
OUTPUT
[['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'f']]
Here's how I would do it.
create a list to store the possible sequences
iterate through the continuation list
copy the original list
append the continuation letter to the copied list
append the copied list to the possible list
def combine_list(list_, cont_list):
# create a list to store the possible sequences
possible_list = []
# iterate through the continuation list
for j in cont_list:
# copy the original list
l2 = list_.copy()
# append the continuation letter to the copied list
l2.append(j)
# append the copied list to the possible list
possible_list.append(l2)
return possible_list
l = ['a', 'b', 'c']
c = ['d', 'f']
print(combine_list(l, c))
Output:
[['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'f']]
Edit
What's wrong with your code?
If you want to copy a list you need to it with list.copy(). If you just do copy = list you are not creating a new list object. if you make changes in copy all changes will apply to list also.
The list.append(element) function does not return a list object it returns None that's why your result looks like this [None, None] you appended None twice.
In Python, append modifies the list it is called on and doesn't return anything (technically it returns None, which is why you ended up with a list full of None). That means that you cannot store the result of append in a variable.
my_list = []
foo = my_list.append(1)
print(foo) # Prints 'None' because that's all that append returns
print(my_list) # Prints '[1]' because the value got added to the original list by append
This is the big difference between lists and strings in Python that beginners sometimes get confused about. Strings are immutable which means they cannot be changed. So methods such as replace return a new string, because they cannot modify the original string. Lists, on the other hand, are mutable, meaning they can be modified. So methods on lists such as append or pop modify the list they are called on rather than returning a new one.
my_string = "Python"
# Needs to be stored in a new variable,
# the original string cannot be modified
new_string = my_string.replace("n", "k")
print(my_string) # Still the original value, Python
print(new_string) # The new modified value, Pythok
my_list = [1, 2]
my_list.append(3) # Modified the list itself, no need to store anything new
print(my_list) # [1, 2, 3]
Also, note that it is an extremely bad idea to call one of your lists list as list is a keyword in Python. (It is used to construct new lists, e.g. list(range(10)) creates a list [0, 1, ..., 9]).
I'm learning python and I have been trying to make an automatic list of lists. For example:
The next list, which I have to split to get a list of separated letters, and then join them again to make a two lists of separated letters
lists=[['a,b,c,h'],['d,e,f,g']]
print('list length', len(lists))
splited=[]
splited1=lists[0][0].split(',')
print(splited1) #['a', 'b', 'c', 'h']
splited2=lists[1][0].split(',')
print(splited2) #['d', 'e', 'f', 'g']
listcomb=[splited1,splited2]
print(listcomb) #[['a', 'b', 'c', 'h'], ['d', 'e', 'f', 'g']]
This is what I want to get, a list that have 2 lists, but in the case I have to get more lists inside that list i want to make it automatic with a for loop.
My try, but it didn't work
listcomb2=zip(splited1,splited2)
print(listcomb2)
sepcomb = list()
print(type(sepcomb))
for x in range(len(lists)):
sep=lists[x][0].split(',')
sepcomb[x]=[sep]
print(sepcomb)
I'm having problems with splitting the letters and then joining them in a new list. Pls help
Make some tweak in your code. As we can see lenght of sepcomb is 0 so use append method to avoid this problem. As sepcomb[x]=[sep] is is assignment to x-index but it x index doesn't exist so, it will raise error
change:
for x in range(len(lists)):
sep=lists[x][0].split(',')
sepcomb[x]=[sep]
to
for x in range(len(lists)):
sep=lists[x][0].split(',')
sepcomb.append(sep)
Method-2
sepcomb = list(i[0].split(',') for i in lists)
You can simply do the following:
final=[splinted1]+[splinted2]
Or a better way directly from the lists variable would be:
final=[value[0].split(',') for value in lists]
Here you go:
lists = [['a,b,c,h'],['d,e,f,g']]
listcomb = []
for each in lists:
splited = each[0].split(',')
listcomb.append(splited)
print(listcomb)
list1 = [['apple','b','c'] ,['dolly','e','f']]
list2 =[['awsme','b','c'] ,['dad','e','f'],['tally','e','f']]
list_combine = [item for sublst in zip(list1, list2) for item in sublst]
print(list_combine)
Expected Output:
list_combine = [['apple','b','c'] ,['dolly','e','f'],['awsme','b','c'] ,['dad','e','f'],['tally','e','f']]
How to merge 2 unequal nested list into single nested list in python
You can just use the '+' operator to join 2 lists.
list_combine = list1 + list2
print(list_combine)
Output
list_combine = [['apple','b','c'] ,['dolly','e','f'],['awsme','b','c'] ,['dad','e','f'],['tally','e','f']]
You may simply concatenate the two lists by defining a new variable like list3 or whatever you call.
Also due to PEP8, I just modified your code in a more Pythonic way so that it would be more readable. Things like space before comma in not suggested, but after that is recommended. This recommendation is not just in Python, but also it is the better way to write in English grammatically too.
You may check this out and inform me should you have any doubts and questions regarding my answer:
list1 = [['apple', 'b', 'c'], ['dolly', 'e', 'f']]
list2 = [['awsme', 'b', 'c'], ['dad', 'e', 'f'], ['tally', 'e', 'f']]
list3 = list1 + list2
print(list3)
I hope it would be useful.
This question already has answers here:
How do I split a string into a list of characters?
(15 answers)
Closed 2 years ago.
I tried using all the methods suggested by others but its not working.
methods like str.split(), lst = list("abcd") but its throwing error saying [TypeError: 'list' object is not callable]
I want to convert string to list for each character in the word
input str= "abc" should give list = ['a','b','c']
I want to get the characters of the str in form of list
output - ['a','b','c','d','e','f'] but its giving ['abcdef']
str = "abcdef"
l = str.split()
print l
First, don't use list as a variable name. It will prevent you from doing what you want, because it will shadow the list class name.
You can do this by simply constructing a list from the string:
l = list('abcedf')
sets l to the list ['a', 'b', 'c', 'e', 'd', 'f']
First of all, don't use list as name of the variable in your program. It is a defined keyword in python and it is not a good practice.
If you had,
str = 'a b c d e f g'
then,
list = str.split()
print list
>>>['a', 'b', 'c', 'd', 'e', 'f', 'g']
Since split by default will work on spaces, it Will give what you need.
In your case, you can just use,
print list(s)
>>>['a', 'b', 'c', 'd', 'e', 'f', 'g']
Q. "I want to convert string to list for each character in the word"
A. You can use a simple list comprehension.
Input:
new_str = "abcdef"
[character for character in new_str]
Output:
['a', 'b', 'c', 'd', 'e', 'f']
Just use a for loop.
input:::
str="abc"
li=[]
for i in str:
li.append(i)
print(li)
#use list function instead of for loop
print(list(str))
output:::
["a","b","c"]
["a","b","c"]
what I basically need is to check every element of a list and if some criteria fit I want to remove it from the list.
So for example let's say that
list=['a','b','c','d','e']
I basically want to write (in principle and not the actual code I try to implement)
If an element of the list is 'b' or 'c' remove it from the list and take the next.
But
for s in list:
if s=='b' or s=='c':
list.remove(s)
fails because when 'b' is removed the loop takes 'd' and not 'c' as the next element. So is there a way to do that faster than storing the elements in a separate list and removing them afterwards?
Thanks.
The easier way is to use a copy of the list - it can be done with a slice that extends "from the beginning" to the "end" of the list, like this:
for s in list[:]:
if s=='b' or s=='c':
list.remove(s)
You have considered this, and this is simple enough to be in your code, unless this list is really big, and in a critical part of the code (like, in the main loop of an action game). In that case, I sometimes use the following idiom:
to_remove = []
for index, s in enumerate(list):
if s == "b" or s == "c":
to_remove.append(index)
for index in reversed(to_remove):
del list[index]
Of course you can resort to a while loop instead:
index = 0
while index < len(list):
if s == "b" or s == "c":
del list[index]
continue
index += 1
Its better not to reinvent things which are already available. Use filter functions and lambda in these cases. Its more pythonic and looks cleaner.
filter(lambda x:x not in ['b','c'],['a','b','c','d','e'])
alternatively you can use list comprehension
[x for x in ['a','b','c','d','e'] if x not in ['b','c']]
This is exactly what itertools.ifilter is designed for.
from itertools import ifilter
ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])
will give you back a generator for your list. If you actually need a list, you can create it using one of the standard techniques for converting a generator to a list:
list(ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e']))
or
[x for x in ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])]
If you are ok with creating a copy of the list you can do it like this (list comprehension):
[s for s in list if s != 'b' and s != 'c']