Extract substrings from a list into a list in Python - python

I have a Python list like:
['user#gmail.com', 'someone#hotmail.com'...]
And I want to extract only the strings after # into another list directly, such as:
mylist = ['gmail.com', 'hotmail.com'...]
Is it possible? split() doesn't seem to be working with lists.
This is my try:
for x in range(len(mylist)):
mylist[x].split("#",1)[1]
But it didn't give me a list of the output.

You're close, try these small tweaks:
Lists are iterables, which means its easier to use for-loops than you think:
for x in mylist:
#do something
Now, the thing you want to do is 1) split x at '#' and 2) add the result to another list.
#In order to add to another list you need to make another list
newlist = []
for x in mylist:
split_results = x.split('#')
# Now you have a tuple of the results of your split
# add the second item to the new list
newlist.append(split_results[1])
Once you understand that well, you can get fancy and use list comprehension:
newlist = [x.split('#')[1] for x in mylist]

That's my solution with nested for loops:
myl = ['user#gmail.com', 'someone#hotmail.com'...]
results = []
for element in myl:
for x in element:
if x == '#':
x = element.index('#')
results.append(element[x+1:])

Related

Replace string in specific index in list of lists python

How can i replace a string in list of lists in python but i want to apply the changes only to the specific index and not affecting the other index, here some example:
mylist = [["test_one", "test_two"], ["test_one", "test_two"]]
i want to change the word "test" to "my" so the result would be only affecting the second index:
mylist = [["test_one", "my_two"], ["test_one", "my_two"]]
I can figure out how to change both of list but i can't figure out what I'm supposed to do if only change one specific index.
Use indexing:
newlist = []
for l in mylist:
l[1] = l[1].replace("test", "my")
newlist.append(l)
print(newlist)
Or oneliner if you always have two elements in the sublist:
newlist = [[i, j.replace("test", "my")] for i, j in mylist]
print(newlist)
Output:
[['test_one', 'my_two'], ['test_one', 'my_two']]
There is a way to do this on one line but it is not coming to me at the moment. Here is how to do it in two lines.
for two_word_list in mylist:
two_word_list[1] = two_word_list.replace("test", "my")

How to compare and remove second element of a nested list using List comprehensions?

So I have a nested list and would like to compare and remove a list inside a nested list based on the condition match.
Here is my code :
def secondValue(val):
return val[1]
if __name__ == '__main__':
nestedList=[]
for _ in range(int(input())):
name = input()
score = float(input())
nestedList.append([name,score]) # Made a nested list from the input
lowestMarks=min(nestedList,key=secondValue) [1] #Extracting the minimum score
newList=[x for x in nestedList[1] if x!=lowestMarks] # PROBLEM HERE
The last line of my code is where I want to remove the list inside my nested list based on condition match. Sure, I can do this with a nested for loop but if there is a way to do this using list comprehension I'd consider that approach.
Basically I'd appreciate an answer that tells how to remove a list from a nested list based on a condition. In my case the list looks like :
[[test,23],[test2,44],......,[testn,23]]
Problems:
for x in nestedList[1] just iterates over second sublist of the nested list.
x is a sublist and it can never be equal to lowestMarks.
Use a list-comprehension as:
newList = [[x, y] for x, y in nestedList if y != lowestMarks]
Mistake was in the below line and is now fixed.
newList=[x for x in nestedList if x[1] != lowestMarks] # PROBLEM HERE
nestedList[1] fetches the second sub-list. You want to iterate over the entire list.

How to merge n lists together item by item for each list

I want to make one large list for entering into a database with values from 4 different lists. I want it to be like
[[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]], etc.....]
Another issue is that currently the data is received like this:
[ [ [list1[0], list1[1], [list1[3]]], [[list2[0]]], etc.....]
I've tried looping through each list using indexs and adding them to a new list based on those but it hasn't worked, I'm pretty sure it didn't work because some of the lists are different lengths (they're not meant to be but it's automated data so sometimes there's a mistake).
Anyone know what's the best way to go about this? Thanks.
First list can be constructed using zip function as follows (for 4 lists):
list1 = [1,2,3,4]
list2 = [5,6,7,8]
list3 = [9,10,11,12]
list4 = [13,14,15,16]
res = list(zip(list1,list2,list3,list4))
For arbitrtary number of lists stored in another list u can use *-notation to unpack outer list:
lists = [...]
res = list(zip(*lists))
To construct list of lists for zipping from you data in second issue use flatten concept to it and then zip:
def flatten(l):
res = []
for el in l:
if(isinstance(el, list)):
res += flatten(el)
else:
res.append(el)
return res
auto_data = [...]
res = list(zip(*[flatten(el) for el in auto_data]))
Some clarification at the end:
zip function construct results of the smallest length between all inputs, then you need to extend data in list comprehension in last code string to be one length to not lose some info.
So if I understand correctly, this is your input:
l = [[1.1,1.2,1.3,1.4],[2.1,2.2,2.3,2.4],[3.1,3.2,3.3,3.4],[4.1,4.2,4.3,4.4]]
and you would like to have this output
[[1.1,2.1,3.1,4.1],...]
If so, this could be done by using zip
zip(*l)
Make a for loop which only gives you the counter variable. Use that variable to index the lists. Make a temporary list , fill it up with the values from the other lists. Add that list to the final one. With this you will et the desired structure.
nestedlist = []
for counter in range(0,x):
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
If all the 4 lists are the same length you can use this code to make it even nicer.
nestedlist = []
for counter in range(0,len(firstlist)): #changed line
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
This comprehension should work, with a little help from zip:
mylist = [i for i in zip(list1, list2, list3, list4)]
But this assumes all the list are of the same length. If that's not the case (or you're not sure of that), you can "pad" them first, to be of same length.
def padlist(some_list, desired_length, pad_with):
while len(some_list) < desired_length:
some_list.append(pad_with)
return some_list
list_of_lists = [list1, list2, list3, list4]
maxlength = len(max(list_of_lists, key=len))
list_of_lists = [padlist(l, maxlength, 0) for l in list_of_lists]
And now do the above comprehension statement, works well in my testing of it
mylist = [i for i in zip(*list_of_lists)]
If the flatten concept doesn't work, try this out:
import numpy as np
myArray = np.array([[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]]])
np.hstack(myArray)
Also that one should work:
np.concatenate(myArray, axis=1)
Just for those who will search for the solution of this problem when lists are of the same length:
def flatten(lists):
results = []
for numbers in lists:
for output in numbers:
results.append(output)
return results
print(flatten(n))

Exclude items from list of lists Python

I have the next list of
testList = []
testList.append([0,-10])
testList.append([-12,122])
testList.append([13,172])
testList.append([17,296])
testList.append([-10,80])
testList.append([-16,230])
testList.append([-18, 296])
testList.append([-2, -8])
testList.append([-5,10])
testList.append([2,-4])
and another lists which contains elements from previous list:
m1 = []
m1.append([0, -10])
m1.append([13, 172])
Then I try to get a subarray from the list testList with the next statement:
[element for i, element in enumerate(testList) if i not in m1]
But I get the same list as testList.
How can I achieve this?
If you don't care about the order in the lists, you can use sets instead:
# result will be a set, not a list
not_in_testlist = set(testlist) - set(m1)
If you want the result to be a list again:
# result will be a list with a new order
not_in_m1 = list(set(testlist) - set(m1))
Be aware that using sets will lose the order of the original lists because sets are unordered types (they use hashing under the hood).
If you need to preserve the order, then Andrew Allaire's answer is correct:
# result is a list, order is preserved
not_in_testlist = [e for e in testlist if e not in m1]
The problem is with your use of enumerate. The i is just going to be an integer, and therefor never in a list that only has lists in it. Try this:
[element for element in testList if element not in m1]
Try with this:
def clean_list(my_list, exclusion_list):
new_list = []
for i in my_list:
if i in exclusion_list:
continue
else:
new_list.append(i)
return new_list

How do I merge a 2D array in Python into one string with List Comprehension?

List Comprehension for me seems to be like the opaque block of granite that regular expressions are for me. I need pointers.
Say, I have a 2D list:
li = [[0,1,2],[3,4,5],[6,7,8]]
I would like to merge this either into one long list
li2 = [0,1,2,3,4,5,6,7,8]
or into a string with separators:
s = "0,1,2,3,4,5,6,7,8"
Really, I'd like to know how to do both.
Like so:
[ item for innerlist in outerlist for item in innerlist ]
Turning that directly into a string with separators:
','.join(str(item) for innerlist in outerlist for item in innerlist)
Yes, the order of 'for innerlist in outerlist' and 'for item in innerlist' is correct. Even though the "body" of the loop is at the start of the listcomp, the order of nested loops (and 'if' clauses) is still the same as when you would write the loop out:
for innerlist in outerlist:
for item in innerlist:
...
Try that:
li=[[0,1,2],[3,4,5],[6,7,8]]
li2 = [ y for x in li for y in x]
You can read it like this:
Give me the list of every ys.
The ys come from the xs.
The xs come from li.
To map that in a string:
','.join(map(str,li2))
There's a couple choices. First, you can just create a new list and add the contents of each list to it:
li2 = []
for sublist in li:
li2.extend(sublist)
Alternately, you can use the itertools module's chain function, which produces an iterable containing all the items in multiple iterables:
import itertools
li2 = list(itertools.chain(*li))
If you take this approach, you can produce the string without creating an intermediate list:
s = ",".join(itertools.chain(*li))
My favorite, and the shortest one, is this:
li2 = sum(li, [])
and
s = ','.join(li2)
EDIT: use sum instead of reduce, (thanks Thomas Wouters!)
For the second one, there is a built-in string method to do that :
>>> print ','.join(str(x) for x in li2)
"0,1,2,3,4,5,6,7,8"
For the first one, you can use join within a comprehension list :
>>> print ",".join([",".join(str(x) for x in li])
"0,1,2,3,4,5,6,7,8"
But it's easier to use itertools.flatten :
>>> import itertools
>>> print itertools.flatten(li)
[0,1,2,3,4,5,6,7,8]
>>> print ",".join(str(x) for x in itertools.flatten(li))
"0,1,2,3,4,5,6,7,8"
N.B : itertools is a module that help you to deal with common tasks with iterators such as list, tuples or string... It's handy because it does not store a copy of the structure you're working on but process the items one by one.
EDIT : funny, I am learning plenty of way to do it. Who said that there was only one good way to do it ?
import itertools
itertools.flatten( li )
To make it a flattened list use either:
http://code.activestate.com/recipes/121294/
http://code.activestate.com/recipes/363051/
Then, join to make it a string.
Here is a way:
def convert2DArrtostring(ndArr):
'''converts 2D array to string'''
arr_str = "["
for i in ndArr:
arr_str += "["
for j in i:
arr_str += str(j) + " "
arr_str += "]\n"
arr_str += "]"
return arr_str
There are many ways to do this problem. I like Numpy's tools because it is normally already imported in everything I do. However, if you aren't using Numpy for anything else this probably isn't a good method.
import numpy
li = [[0,1,2],[3,4,5],[6,7,8]]
li2=li[0] #first element of array to merge
i=1
while i<len(li):
li2=numpy.concatenate((li2,li[i]))
i+=1
print li2
This would print [0 1 2 3 4 5 6 7 8] and then you can convert this into your string too.

Categories