Converting a list - python

I have a list similar to the one shown below. Do you have any ideas on how I can convert it to the one in the EXPECTED OUTPUT section below?
list =['username1,username2', 'username3','username4,username5']
EXPECTED OUTPUT:-
list = ['username1','username2', 'username3','username4','username5']
Thanks

>>> alist = ['username1,username2', 'username3','username4,username5']
>>> ','.join(alist).split(',')
['username1', 'username2', 'username3', 'username4', 'username5']
By the way, don't use list as the variable name.

you can also use
>>> alist = ['username1,username2', 'username3','username4,username5']
>>> [j for i in alist for j in i.split(',')]
but #zhangyangyu's method is faster
>>> import timeit
>>> timeit.timeit("[j for i in ['username1,username2', 'username3','username4,us
ername5'] for j in i.split(',')]", number=10000)
0.05875942333452144
>>> timeit.timeit("','.join(['username1,username2', 'username3','username4,usern
ame5']).split(',')", number=10000)
0.023530085527625033

Related

Remove list from list of lists if criterion is met

I am looking to program a small bit of code in Python. I have a list of lists called "keep_list", from which I want to remove any sublist containing a specific value found in another list called "deleteNODE".
for example:
deleteNODE=[0,4]
keep_list=[[0,1,2],[0,2,3],[1,2,3],[4,5,6]]
After running the code the result should be (removing any list containing 0 or 4):
keep_list=[[1,2,3]]
Is there any efficient way of doing this?
I did it like this:
[x for x in keep_list if not set(x).intersection(deleteNODE)]
Since I thought the other answers were better, I also ran timeit on all the 3 answers and surprisingly this one was faster.
Python 3.8.2
>>> import timeit
>>>
>>> deleteNODE=[0,4]
>>> keep_list=[[0,1,2],[0,2,3],[1,2,3],[4,5,6]]
>>>
>>>
>>> def v1(keep, delete):
... return [l for l in keep_list if not any(n in l for n in deleteNODE)]
...
>>> def v2(keep, delete):
... return [i for i in keep_list if len(set(i)&set(deleteNODE)) == 0]
...
>>> def v3(keep, delete):
... return [x for x in keep_list if not set(x).intersection(deleteNODE)]
...
>>>
>>> timeit.timeit(lambda: v1(keep_list, deleteNODE), number=3000000)
7.2224646
>>> timeit.timeit(lambda: v2(keep_list, deleteNODE), number=3000000)
7.1723587
>>> timeit.timeit(lambda: v3(keep_list, deleteNODE), number=3000000)
5.640403499999998
I'm no Python expert so can anyone understand why mine was faster since it appears to be creating a new set for every evaluation?
You can solve this using a list comprehension to cycle through each list within the larger list and by using sets. The & operator between sets returns the intersection (the elements common between both sets). Therefore, if the intersection between the list you're evaluating and deleteNODE is not zero, that means there is a common element and it gets excluded.
keep_list = [i for i in keep_list if len(set(i)&set(deleteNODE)) == 0]
This could be done using list comprehension
deleteNODE=[0,4]
keep_list=[[0,1,2],[0,2,3],[1,2,3],[4,5,6]]
...
keep_list = [l for l in keep_list if not any(n in l for n in deleteNODE)]

splitting a list in a better way using list comprehension

I have a simple list that I am splitting and concatenating. My code uses for loop and if condition and ugly. Can you suggest a better way using list comprehension?
My code
mylist = ['10.10.10.1','10.10.10.2,10.10.10.3,10.10.10.4,10.10.10.5','10.10.10.6']
mylist = [i.split(",") for i in mylist]
list =[]
for x,y in enumerate(mylist):
if len(y) == 1:
list.append(y[0])
else:
for z in y:
list.append(z)
print(list)
I am getting the below result and exactly the way i want
['10.10.10.1','10.10.10.2','10.10.10.3','10.10.10.4','10.10.10.5','10.10.10.6']
You want:
[s for string in mylist for s in string.split(',')]
Note, your original approach wouldn't be so bad if you just simplified. No need for enumerate and no need to check the length, so just:
final_list =[]
for sub in mylist:
for s in sub:
final_list.append(s)
By the way, you shouldn't shadow the built-in list. Use another name
I agree with #juanpa.arrivillaga. However hope we can avoid that second looping since he is checking for empty values returning while splitting
In [7]: s=['10.10.10.1','','10.10.10.2,10.10.10.3,10.10.10.4,10.10.10.5','10.10.10.6']
In [8]: [splitRec for rec in s for splitRec in rec.split(',') if splitRec]
Out[8]:
['10.10.10.1',
'10.10.10.2',
'10.10.10.3',
'10.10.10.4',
'10.10.10.5',
'10.10.10.6']
In [9]: s=['10.10.10.1',',,','10.10.10.2,10.10.10.3,10.10.10.4,10.10.10.5','10.10.10.6']
In [10]: [splitRec for rec in s for splitRec in rec.split(',') if splitRec]Out[10]:
['10.10.10.1',
'10.10.10.2',
'10.10.10.3',
'10.10.10.4',
'10.10.10.5',
'10.10.10.6']
Not a comprehension, but good anyway, I think.
','.join(mylist).split(',')
You can first just split each string on ',':
>>> mylist = ['10.10.10.1','10.10.10.2,10.10.10.3,10.10.10.4,10.10.10.5','10.10.10.6']
>>> split_str = [x.split(',') for x in mylist]
>>> split_str
[['10.10.10.1'], ['10.10.10.2', '10.10.10.3', '10.10.10.4', '10.10.10.5'], ['10.10.10.6']]
Then if you want to flatten it, you can use itertools.chain.from_iterable:
>>> from itertools import chain
>>> list(chain.from_iterable(split_str))
['10.10.10.1', '10.10.10.2', '10.10.10.3', '10.10.10.4', '10.10.10.5', '10.10.10.6']

How do I convert multiple lists inside a list using Python? [duplicate]

This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 7 years ago.
I want to convert multiple lists inside a list? I am doing it with a loop, but each sub list item doesn't get a comma between it.
myList = [['a','b','c','d'],['a','b','c','d']]
myString = ''
for x in myList:
myString += ",".join(x)
print myString
ouput:
a,b,c,da,b,c,d
desired output:
a,b,c,d,a,b,c,d
This can be done using a list comprehension where you will "flatten" your list of lists in to a single list, and then use the "join" method to make your list a string. The ',' portion indicates to separate each part by a comma.
','.join([item for sub_list in myList for item in sub_list])
Note: Please look at my analysis below for what was tested to be the fastest solution on others proposed here
Demo:
myList = [['a','b','c','d'],['a','b','c','d']]
result = ','.join([item for sub_list in myList for item in sub_list])
output of result -> a,b,c,d,a,b,c,d
However, to further explode this in to parts to explain how this works, we can see the following example:
# create a new list called my_new_list
my_new_list = []
# Next we want to iterate over the outer list
for sub_list in myList:
# Now go over each item of the sublist
for item in sub_list:
# append it to our new list
my_new_list.append(item)
So at this point, outputting my_new_list will yield:
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']
So, now all we have to do with this is make it a string. This is where the ','.join() comes in to play. We simply make this call:
myString = ','.join(my_new_list)
Outputting that will give us:
a,b,c,d,a,b,c,d
Further Analysis
So, looking at this further, it really piqued my interest. I suspect that in fact the other solutions are possibly faster. Therefore, why not test it!
I took each of the solutions proposed, and ran a timer against them with a much bigger sample set to see what would happen. Running the code yielded the following results in increasing order:
map: 3.8023074030061252
chain: 7.675725881999824
comprehension: 8.73164687899407
So, the clear winner here is in fact the map implementation. If anyone is interested, here is the code used to time the results:
from timeit import Timer
def comprehension(l):
return ','.join([i for sub_list in l for i in sub_list])
def chain(l):
from itertools import chain
return ','.join(chain.from_iterable(l))
def a_map(l):
return ','.join(map(','.join, l))
myList = [[str(i) for i in range(10)] for j in range(10)]
print(Timer(lambda: comprehension(myList)).timeit())
print(Timer(lambda: chain(myList)).timeit())
print(Timer(lambda: a_map(myList)).timeit())
from itertools import chain
myList = [['a','b','c','d'],['a','b','c','d']]
print(','.join(chain.from_iterable(myList)))
a,b,c,d,a,b,c,d
You could also just join at both levels:
>>> ','.join(map(','.join, myList))
'a,b,c,d,a,b,c,d'
It's shorter and significantly faster than the other solutions:
>>> myList = [['a'] * 1000] * 1000
>>> from timeit import timeit
>>> timeit(lambda: ','.join(map(','.join, myList)), number=10)
0.18380278121490046
>>> from itertools import chain
>>> timeit(lambda: ','.join(chain.from_iterable(myList)), number=10)
0.6535200733309843
>>> timeit(lambda: ','.join([item for sub_list in myList for item in sub_list]), number=10)
1.0301431917067738
I also tried [['a'] * 10] * 10, [['a'] * 10] * 100000 and [['a'] * 100000] * 10 and it was always the same picture.
myList = [['a','b','c','d'],[a','b','c','d']]
smyList = myList[0] + myList[1]
str1 = ','.join(str(x) for x in smyList)
print str1
output
a,b,c,d,a,b,c,d

Applying regex on each item of a list in Python

If I apply this regex:
re.split(r"(^[^aeiou]+)(?=[aeiouy])", "janu")
on the string "janu", it gives the following result: ['', 'j', 'anu']
Now I want to apply this regex on the following list to get the similar results for each item as above. Can a for loop be used, and if yes, how?
lista = ['janu', 'manu', 'tanu', 'banu']
You can use a list comprehension:
>>> from re import split
>>> lista = ['janu', 'manu', 'tanu', 'banu']
>>> [split("(^[^aeiou]+)(?=[aeiouy])", x)[1]+"doc" for x in lista]
['jdoc', 'mdoc', 'tdoc', 'bdoc']
>>>
Edit regarding comment:
This will work:
>>> from re import split
>>> lista = ['janu', 'manu', 'tanu', 'banu']
>>> listb = []
>>> for item in lista:
... data = split("(^[^aeiou]+)(?=[aeiouy])", item)
... listb.append(data[2]+data[1]+"doc")
...
>>> listb
['anujdoc', 'anumdoc', 'anutdoc', 'anubdoc']
>>>
Use the list comprehension
[re.split(r"(^[^aeiou]+)(?=[aeiouy])", i) for i in list]
You can use a for loop but this is considered the pythonic way to do things.

How to find common elements in list of lists?

I'm trying to figure out how to compare an n number of lists to find the common elements.
For example:
p=[ [1,2,3],
[1,9,9],
..
..
[1,2,4]
>> print common(p)
>> [1]
Now if I know the number of elements I can do comparions like:
for a in b:
for c in d:
for x in y:
...
but that wont work if I don't know how many elements p has. I've looked at this solution that compares two lists
https://stackoverflow.com/a/1388864/1320800
but after spending 4 hrs trying to figure a way to make that recursive, a solution still eludes me so any help would be highly appreciated!
You are looking for the set intersection of all the sublists, and the data type you should use for set operations is a set:
result = set(p[0])
for s in p[1:]:
result.intersection_update(s)
print result
A simple solution (one-line) is:
set.intersection(*[set(list) for list in p])
The set.intersection() method supports intersecting multiple inputs at a time. Use argument unpacking to pull the sublists out of the outer list and pass them into set.intersection() as separate arguments:
>>> p=[ [1,2,3],
[1,9,9],
[1,2,4]]
>>> set(p[0]).intersection(*p)
set([1])
Why not just:
set.intersection(*map(set, p))
Result:
set([1])
Or like this:
ip = iter(p)
s = set(next(ip))
s.intersection(*ip)
Result:
set([1])
edit:
copied from console:
>>> p = [[1,2,3], [1,9,9], [1,2,4]]
>>> set.intersection(*map(set, p))
set([1])
>>> ip = iter(p)
>>> s = set(next(ip))
>>> s.intersection(*ip)
set([1])
p=[ [1,2,3],
[1,9,9],
[1,2,4]]
ans = [ele[0] for ele in zip(*p) if len(set(ele)) == 1]
Result:
>>> ans
[1]
reduce(lambda x, y: x & y, (set(i) for i in p))
You are looking for the set intersection of all the sublists, and the data type you should use for set operations is a set:
result = set(p[0])
for s in p[1:]:
result.intersection_update(s)
print result
However, there is a limitation of 10 lists in a list. Anything bigger causes 'result' list to be out of order. Assuming you've made 'result' into a list by list(result).
Make sure you result.sort() to ensure it's ordered if you depend on it to be that way.

Categories