List re-formatting in python - python

I have a list like this:
my_list = ['a,b,c']
Then I wanna reformat the list to
new_list = ["a","b","c"]
Can someone give a hand, I'm a newbie in Python. Thanks!

You can try this:-
my_list = ['a,b,c']
new_list = my_list[0].split(',')
print(new_list)
Output:-
['a', 'b', 'c']

Please note that the first list holds only 1 item which is a string.
So, you can use split() method to split the string into an array as followings:
my_list = ['a,b,c']
new_list = my_list[0].split(",")
## ^^^ This is to get the first item since the array has only 1 item

Related

How to delete all elements only that i want?

I'm really beginer of python and i'm wondering how to remove all same elements that i want
I know i can remove a one element with list.remove('target') but it just happen once,
I googled about it but they just say use 'for' or 'while' but i don't know how to do it with a smart way
example , when i have list "apple" i want to make it "ale" with parameter'p'
I tried
list = ['a','p','p','l','e']
for i in list:
list.remove('p')
but i got error that 'ValueError: list.remove(x): x not in list'
(My English might sucks because i'm Korean :( and it's my first ask in stackoverflow )
First you should not be using list as a variable name as list is a built-in type in python.
See: Built-in types in python
For your question, you can use list comprehension for this.
eg:
my_list = ['a','p','p','l','e']
element_to_remove = 'p'
new_list = [item for item in my_list if item != element_to_remove]
# new_list = ['a', 'l', 'e']
You can convert the list to set (so that there will be no repetitions) and convert it back to list. After, remove the element you want.
my_list = ['a','p','p','l','e']
my_list2 = my_list(set(my_list))
my_list.remove('p')
Try list comprehension:
[i for i in l if i not in ('p',)]
where l is your list.

Replace elements in a list of lists python

I have a list of lists as follows:
list=[]
*some code to append elements to list*
list=[['a','bob'],['a','bob'],['a','john']]
I want to go through this list and change all instances of 'bob to 'b' and leave others unchanged.
for x in list:
for a in x:
if "bob" in a:
a.replace("bob", 'b')
After printing out x it is still the same as list, but not as follows:
list=[['a','b'],['a','b'],['a','john']]
Why is the change not being reflected in list?
Because str.replace doesn't work in-place, it returns a copy. As immutable objects, you need to assign the strings to elements in your list of lists.
You can assign directly to your list of lists if you extract indexing integers via enumerate:
L = [['a','bob'],['a','bob'],['a','john']]
for i, x in enumerate(L):
for j, a in enumerate(x):
if 'bob' in a:
L[i][j] = a.replace('bob', 'b')
Result:
[['a', 'b'], ['a', 'b'], ['a', 'john']]
More Pythonic would be to use a list comprehension to create a new list. For example, if only the second of two values contains names which need checking:
L = [[i, j if j != 'bob' else 'b'] for i, j in L]
You can try using a dictionary object of python
import numpy as np
L = [['a','bob'],['a','bob'],['a','john']]
dic = {'bob':'b'} # you can specify more changes here
new_list = [dic.get(n, n) for n in np.concatenate(L)]
print(np.reshape(new_list,[-1,2]).tolist())
Result is
[['a', 'b'], ['a', 'b'], ['a', 'john']]
I'm going to use a simple example, but basically x is another variable and isn't linked to the list element. You have to change the list element directly in order to alter the list.
l=[1,2,3,4]
for x in l:
x=x+1
This doesn't change the list
l=[1,2,3,4]
for i,x in enumerate(l):
l[i]=x+1
this changes the list
I might be a little to the party, but a more Pythonic way of doing this is using a map and a list comprehension. It can operate on a list of the list with any number of values.
l = [['a','bob'],['a','bob'],['a','john']]
[list(map(lambda x: x if x != 'bob' else 'b', i)) for i in l]
it gives you the desired output
[['a', 'b'], ['a', 'b'], ['a', 'john']]
The main idea is that the inner loop is iterating through the inner loop and using the simple lambda function to perform the replacement.
I hope that this helps anyone else who is looking out for something similar.
This is the case because you are only changing the temporary variable a.
list = [1,2,3]
for i in list:
i+=1
list will still be [1,2,3]
you have to edit the string based on its index in the list

If statement that keeps characters only

Let's say we have a list list_a = [a,b,C,.,/,!,d,E,f,]
i want to append to a new list only the letters of the alphabet.
So the new list will be list_b = [a,b,C,d,E,f].
So far i have tried doing it like that way:
list_b = []
for elements in list_a:
try:
if elements == str(elements):
list_b.append(elements)
except ValueError: #Catches the Error when the element is not a letter
continue
However, when i print the list_b it has all the elements of list_a , it doesn't do the job i expected.
Any ideas ?
PS: comma in the specific example brings Error too.
You can use the .isalpha() method of the string type.
In [1]: list_a = ['a','b','C','.','/','!','d','E','f']
In [2]: list_b = [i for i in list_a if i.isalpha()]
In [3]: list_b
Out[3]: ['a', 'b', 'C', 'd', 'E', 'f']
Try checking if the character is an alphabet by using the .isalpha() function.
list_b = []
for elements in list_a:
if elements.isalpha():
list_b.append(elements)
You are missing the fact that the str() function does not return the "str" elements you think it does, just an str representation of them.
Try creating a list with you dictionary [a-zA-Z] (not very pythonic but simple to grasp) and check if your character exists in it.
I suggest writing your own code from scratch instead of copy/pasting, that is the only way to really understand the problem....
You can try this:
import string
for item in list_a:
if item in string.ascii_letters:
list_b.append(item)
Also, check out the string module. It has a lot of additional methods that can help you, should you wish to work with strings. Do note that this works only with ascii characters. If you want to check for every character in an alphabet, then you can via the isalpha() method, as the others have noted above.
Well, it is basically the same logic of using isalpha() method, but you can do this by using filter:
list_a = ['a','b','C','.','/','!','d','E','f']
list_b = list(filter(lambda i: i.isalpha(), list_a))
print(list_b)
Output:
['a', 'b', 'C', 'd', 'E', 'f']
You can use the string or re package to do this
import re
new_list = [c for c in old_list if re.match(r'[a-zA-Z]', c)]
Or with string
import string
new_list = [c for c in old_list if c in string.ascii_letters]

List index out of range error

So I am getting a list index out of range error in python again, and I can't figure out what's wrong.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
f1 = open("membrane_GO.txt","r")
new_list1 = f1.readlines()
new_list2 = new_list1
for i in range(len(new_list1)):
if "Reactome" in new_list1[i]:
new_list2.pop(i)
print new_list2
f1.close()
I made sure that the a duplicated list is being modified as the primary list is iterated over, so that can't be the problem.
Appreciate any help
Thanks :)
You only duplicated a reference to the list. If you want to make a separate copy of a list, use slices: list2 = list1[:] or look into the deepcopy module.
When you pop, the array size goes down. That means if the list has length 10, and you pop(0), then the list has length 9. If you then pop(9), which doesn't exist it will give you an out of bounds error.
Example:
>>> x = [0,1,2,3,4]
>>> print x, len(x)
[0,1,2,3,4], 5
>>> x.pop(0)
>>> print x, len(x)
[1,2,3,4], 4
This is an error in your case because you go from 0 to len(new_list1).
The approach I advise you to take is to create a new list where "Reactome" is not in new_list1[i].
You can do this easily in a list comprehension.
with open("membrane_GO.txt","r") as f:
lines = [line for line in f.readlines() if "Reactome" not in line]
print lines
Assume that your list is initially ['a', 'b', 'c'],
then list1 = list2 = ['a', 'b', 'c']
Then you perform iteration for len(list2), ie 3 times,
Then i will take values 0, 1, and 2.
In each iteration you are removing one element from list1.
i = 0
remove list1[0]
new list = ['b', 'c']
i = 1
remove list1[1]
new list = ['b']
i = 2
remove list[2] which does not exist.
So you will get a index out of bound error
Just to add to TigerHawks answer:
Because you have only duplicated the reference (not the list itself), when you pop() an element out of new_list2, you also remove it from new_list1 beceause they're both references to the same list.
Say there are 'n' elements in new_list1 at the start of the loop. It will run for 'n' iterations.
Suppose then that you pop an element out of new_list2 (and so out of new_list1 as well), within the loop, you will get an index out of range error when the loop tries to access the 'nth' element of a list which now only has 'n-1' elements in it
For this to work properly use slicing to copy the list:
new_list2 = new_list1[:]
Incidentally, for i in range(len(new_list1)): is considered un-pythonic, I believe. A 'better' way would be to use enumerate:
for index, element in enumerate(new_list1):
if "Reactome" in element:
new_list2.pop(index)

python parse string and turn into dictionary input

this is my list:
list1 = ('/a/b/c/Hello1/d/e','/a/b/c/Hello2/d/e','/a/b/c/Hello3/d/e')
list2 = []
for x in list1:
y = x.split('/')[4]
list2.append(y)
list2 = ['Hello1', 'Hello2', 'Hello3']
Now I want to create a dictionary where Hello[1-3] is my key and the corresponding string '/a/b/c/Hello[1-3]/d/e' is the value.
How can I connect key and value in python. I am sure this is fairly easy, but I don't know.
Thank you.
You can use a dict comprehension to achieve this.
>>> {s.split('/')[4] : s for s in list1}
{'Hello2': '/a/b/c/Hello2/d/e',
'Hello3': '/a/b/c/Hello3/d/e',
'Hello1': '/a/b/c/Hello1/d/e'}
Assuming that you have the same number of elements in list1 and list2:
dict(zip(list2, list1))

Categories