I have a list of lists like this:
[["testo=text1","testo2=text2"],["testo3=text3","testo4=text4"]]
I want to split each element of each sublist by "=".
Desired result:
[['testo', 'text1'],['testo2', 'text2']]
My attempt was to iterate over each sub-list and split. But it's not working:
[j.split("=") for j in [i for i in splitted_params]]
keep getting 'list' object has no attribute 'split' error
try:
l = [["testo=text1","testo2=text2"],["testo3=text3","testo4=text4"]]
new_l = [inner_element.split("=") for x in l for inner_element in x]
print(new_l)
output:
[['testo', 'text1'], ['testo2', 'text2'], ['testo3', 'text3'], ['testo4', 'text4']]
You shouldn't try to be clever with python list comprehensions. In my opinion, you should go for the readable solution. :)
if __name__ == '__main__':
data = [
["testo=text1","testo2=text2"],
["testo3=text3","testo4=text4"]
]
for arr in data:
for index in range( len(arr) ):
arr[index] = arr[index].split('=')
print(data)
In your expression, [j.split("=") for j in [i for i in splitted_params]], the inner expression, [i for i in splitted_params] is evaluated first, which gives you a list. You did nothing in this list comprehension. Then, when you evaluate [j.split("=") for j in SOME_RESULT_YOU_GOT], you are trying to split a list, which is not possible.
You can use chain.from_iterable() to avoid the double for loop in the list comprehension:
from itertools import chain
l = [["testo=text1", "testo2=text2"], ["testo3=text3", "testo4=text4"]]
[i.split('=') for i in chain.from_iterable(l)]
# [['testo', 'text1'], ['testo2', 'text2'], ['testo3', 'text3'], ['testo4', 'text4']]
Explanation why your solution doesnât work:
splitted_params = [["testo=text1", "testo2=text2"], ["testo3=text3", "testo4=text4"]]
print([i for i in splitted_params] == splitted_params)
# True
So when you use [i for i in splitted_params] inside your listcomp you get the same list.
I think the problem is that [i for i in splitted_params] this doesn't return the lists in your list of lists.
it just returns your list of lists so when you then loop through it again, it will try to split the lists in the list of lists.
so I would suggest you just do a loop in a loop like this
listoflists = [["testo=text1", "testo2=text2"], ["testo3=text3", "testo4=text4"]]
for i in listoflists:
for j in i:
print(j.split("="))
It may not be as pretty but it does get the job done.
Related
I'm trying to do an exercise where I have a list:
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
And I have to make a second list out of it that looks like this:
list_2 = [['chocolate', 1.20], ['book', 5.50], ['hat', 3.25]]
In the second list the numbers have to be floats and without the ' '
So far I've come up with this code:
for item in list_1:
list_2.append(item.split(';'))
The output looks about right:
[['chocolate', '1.20'], ['book', '5.50'], ['hat', '3.25']]
But how do I convert those numbers into floats and remove the double quotes?
I tried:
for item in list_2:
if(item.isdigit()):
item = float(item)
Getting:
AttributeError: 'list' object has no attribute 'isdigit'
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
list_2 = [x.split(';') for x in list_1]
list_3 = [[x[0], float(x[1])] for x in list_2]
item is a list like ['chocolate', '1.20']. You should be calling isdigit() on item[1], not item. But isdigit() isn't true when the string contains ., so that won't work anyway.
Put the split string in a variable, then call float() on the second element.
for item in list_1:
words = item.split(';')
words[1] = float(words[1])
list_2.append(words)
I don't know if this helpful for you.
But,I think using function is better than just using simple for loop
Just try it.
def list_map(string_val,float_val):
return [string_val,float_val]
def string_spliter(list_1):
string_form=[]
float_form=[]
for string in list_1:
str_val,float_val=string.split(";")
string_form.append(str_val)
float_form.append(float_val)
return string_form,float_form
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
string_form,float_form=string_spliter(list_1)
float_form=list(map(float,float_form))
output=list(map(list_map,string_form,float_form))
print(output)
Your way of creating list_2 is fine. To then make your new list, you can use final_list = [[i[0], float(i[1])] for i in list_2]
You could also do it in the for loop like this:
for item in list_1:
split_item = item.split(';')
list_2.append([split_item[0], float(split_item[1])])
This can be achieved in two lines of code using list comprehensions.
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
list_2 = [[a, float(b)] for x in list_1 for a, b in [x.split(';', 1)]]
The second "dimension" to the list comprehension generates a list with a single sublist. This lets us essentially save the result of splitting each item and then bind those two items to a and b to make using them cleaner that having to specify indexes.
Note: by calling split with a second argument of 1 we ensure the string is only split at most once.
You can use a function map to convert each value.
def modify_element(el):
name, value = el.split(';')
return [name, float(value)]
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
result = list(map(modify_element, list_1))
For a problem like this you can initialize two variables for the result of calling the split function and then append a list of both values and call the builtin float function on the second value.
array = []
for i in a_list:
string, number = i.split(";")
array.append([string, float(number)])
print(array)
I have a list List:
List = [-2,9,4,-6,7,0,1,-4]
For numbers less than zero (0) in the list , I would like to skip those numbers and form another list.
Example:-
List = [9,4,7,0,1]
This is a kind of doubt I have, not sure If we can achieve. If it's possible to achieve, can anyone please post here.
You have many options to achieve that. With a list comprehension you can do:
my_list = [i for i in my_list if i >= 0]
With filter():
my_list = filter(lambda i: i >= 0, my_list)
Note:
In Python 3, filter() returns a filter object (not list), to convert it to a list, you can do:
my_list = list(filter(lambda i: i >= 0, my_list))
First use lower case for variable names, second don't use list because it reserved name.
Then just do an if inside the list comprehension
my_list = [i for i in init_list if i >= 0 ]
I have tried this code here my_list = [i for i in init_list if i >= 0 ] but i had modified it to fit to my use and i would like to say that it can be used like this:
for i in [x for x in range(10) if != 3]
I used it here to make the program skip a iteration.
I have a big list in python like this small example:
small example:
['MLEEDMEVAIKMVVVGNGAVGKSSMIQRYCKGIFTKDYKKTIGVDFLERQIQVNDEDVRLMLWDTAGQEEFDAITKAYYRGAQACVLVFSTTDRESFEAV', 'MDHTEGSPAEEPPAHAPSPGKFGERPPPKRLTREAMRNYLKERGDQTVLILHAKVAQKSYGNEKRFFCPPPCVYLMGSGWKKKKEQMERDGCSEQESQPCAFIGIGNSDQEMQQLNLEGKNYCTAKTLYISDSDKRKHFMLSVKMFYGNSDDIGVFLSKRIKVISKPSKKKQSLKNADLCIASGTKVALFNRLRSQTVSTRYLHVEGGNFHASSQQWGAFFIHLLDDDESEGEEFTVRDGYIHYGQTVKLVCSVTGMALPRLIIRKVDKQTALLDADDPVSQLHKCAFYLKDTERMYLCLSQERIIQFQATPCPKEPNKEMINDGASWTIISTDKAEYTFYEGMGPVLAPVTPVPVVESLQLNGGGDVAMLELTGQNFTPNLRVWFGDVEAETMYRCGESMLCVVPDISAFREGWRWVRQPVQVPVTLVRNDGIIYSTSLTFTYTPEPGPRPHCSAAGAILRANSSQVPPNESNTNSEGSYTNASTNSTSVTSSTATVVS']
in the file there are many items and each item is a sequence of characters. I want to make a new list in which every item has only one W. the expected output for the small example would be like the expected output.
expected output:
['MLEEDMEVAIKMVVVGNGAVGKSSMIQRYCKGIFTKDYKKTIGVDFLERQIQVNDEDVRLMLWDTAGQEEFDAITKAYYRGAQACVLVFSTTDRESFEAV']
I am trying to do that in python and wrote the following code:
newlist = []
for item in mylist:
for c in item:
if c == W:
newlist.append(item)
but it does not return what I want. do you know how to fix it?
Use .count
Ex:
res = []
mylist = ['MLEEDMEVAIKMVVVGNGAVGKSSMIQRYCKGIFTKDYKKTIGVDFLERQIQVNDEDVRLMLWDTAGQEEFDAITKAYYRGAQACVLVFSTTDRESFEAV', 'MDHTEGSPAEEPPAHAPSPGKFGERPPPKRLTREAMRNYLKERGDQTVLILHAKVAQKSYGNEKRFFCPPPCVYLMGSGWKKKKEQMERDGCSEQESQPCAFIGIGNSDQEMQQLNLEGKNYCTAKTLYISDSDKRKHFMLSVKMFYGNSDDIGVFLSKRIKVISKPSKKKQSLKNADLCIASGTKVALFNRLRSQTVSTRYLHVEGGNFHASSQQWGAFFIHLLDDDESEGEEFTVRDGYIHYGQTVKLVCSVTGMALPRLIIRKVDKQTALLDADDPVSQLHKCAFYLKDTERMYLCLSQERIIQFQATPCPKEPNKEMINDGASWTIISTDKAEYTFYEGMGPVLAPVTPVPVVESLQLNGGGDVAMLELTGQNFTPNLRVWFGDVEAETMYRCGESMLCVVPDISAFREGWRWVRQPVQVPVTLVRNDGIIYSTSLTFTYTPEPGPRPHCSAAGAILRANSSQVPPNESNTNSEGSYTNASTNSTSVTSSTATVVS']
for item in mylist:
if item.count("W") == 1:
res.append(item)
print(res)
or
res = [item for item in mylist if item.count("W") == 1]
Output:
['MLEEDMEVAIKMVVVGNGAVGKSSMIQRYCKGIFTKDYKKTIGVDFLERQIQVNDEDVRLMLWDTAGQEEFDAITKAYYRGAQACVLVFSTTDRESFEAV']
The problem is you are iterating each character in each string and appending when a condition is met. Moreover, your logic can't "undo" a list.append operation if another W is found. So if W is met twice in a string, you are appending twice.
Instead, you can use a list comprehension with list.count:
res = [i for i in L if i.count('W') == 1]
I have a list List:
List = [-2,9,4,-6,7,0,1,-4]
For numbers less than zero (0) in the list , I would like to skip those numbers and form another list.
Example:-
List = [9,4,7,0,1]
This is a kind of doubt I have, not sure If we can achieve. If it's possible to achieve, can anyone please post here.
You have many options to achieve that. With a list comprehension you can do:
my_list = [i for i in my_list if i >= 0]
With filter():
my_list = filter(lambda i: i >= 0, my_list)
Note:
In Python 3, filter() returns a filter object (not list), to convert it to a list, you can do:
my_list = list(filter(lambda i: i >= 0, my_list))
First use lower case for variable names, second don't use list because it reserved name.
Then just do an if inside the list comprehension
my_list = [i for i in init_list if i >= 0 ]
I have tried this code here my_list = [i for i in init_list if i >= 0 ] but i had modified it to fit to my use and i would like to say that it can be used like this:
for i in [x for x in range(10) if != 3]
I used it here to make the program skip a iteration.
lis a list that I want to explore in order to suppress some items. The function do.i.want.to.suppres.i returns TRUE or FALSE in order to tell me whether I want the suppression. The details of this function is not important.
I tried this:
l = [1,4,2,3,5,3,5,2]
for i in l:
if do.i.want.to.suppress.i(i):
del i
print l
but l does not change! So I tried
l = [1,4,2,3,5,3,5,2]
for position,i in enumerate(l):
if do.i.want.to.suppress.i(i):
del l[position]
But then the problem is that the position does not match the object i as lget modified during the loop.
I could do something like this:
l = [1,4,2,3,5,3,5,2]
for position,i in enumerate(l):
if do.i.want.to.suppress.i(i):
l[position] = 'bulls'
l = [x for x in l if x!='bulls']
But I guess there should have a smarter solution. Do you have one?
l = [item for item in my_list if not do_I_suppress(item)]
List comprehensions! learn them! love them! live them!
The list comprehension approach is the most pythonic way, but if you really need to modify the list itself then I found this to be the best approach, nicer than the while loop approach:
for position in xrange(len(l) - 1, -1, -1):
i = l[position]
if do.i.want.to.suppress.i(i):
del l[position]
This is a good place to use a while loop
i = 0
while i < len(l):
if do.i.want.to.suppress.i(i):
del l[i]
else:
i = i + 1
Besides List Comprehension (which returns a list, creating the full list in memory):
filtered_list = [itm for itm in lst if i_want_to_keep(itm)]
You can use filter() (same result as List Comprehensions)
filtered_list = filter(i_want_to_keep, lst)
or itertools.ifilter() (which returns an iterator and avoid creating the whole list in memory, specially useful for iterating)
import itertools
filtered_list = itertools.ifilter(i_want_to_keep, lst)
for itm in filtered_list:
do_whatever(itm)
filter will also work:
answer = filter(lambda x: not do_I_suppress(x), lis)
Note that in Python 3.x, you will need to put filter in list:
answer = list(filter(lambda x: not do_I_suppress(x), lis))