Removing list having empty list - python

I have the following list:
a = [[['trial1', 'trial2'], 4], [[], 2]]
and I want to remove the list that have inside an empty list.So the following result:
c = [[['trial1', 'trial2'], 4]]
I am using the following code:
c = []
for b in a:
temp =[x for x in b if x]
if len(temp)>1:
c.append(temp)
It works ok, but it seems not to be a 'good way' of doing this task. Is there a more elegant way?

c = [l for l in a if [] not in l]

Use a list comprehension:
c = [x for x in a if [] not in x]

You could use list comprehension and all function to check whether everything in the list evaluted to the True:
c = [i for i in a if all(i)]
print(c)
[[['trial1', 'trial2'], 4]]

You may use filter built-in function.
a = [[['trial1', 'trial2'], 4], [[], 2]]
assert filter(lambda o: [] not in o, a) == [[['trial1', 'trial2'], 4]]
Since in Python 3 filter is lazy, you may need explicit conversion to list.
assert list(filter(lambda o: [] not in o, a)) == [[['trial1', 'trial2'], 4]]

Related

Filter nested list with list comprehension based on other list in python

I have two lists like this:
a = [[1,2,3],[2,3,4],[5,6,7],[7,8,9]]
b = [1,2]
I would now like to filter list a, to keep only the items which contain the items in list b. So the desired output would look like this:
[[1,2,3],[2,3,4]]
I have tried some nested list comprehensions, which I could think of, but could not get the desired output. Any advice is appreciated.
you could try something like this :
print([i for i in a if any(map(i.__contains__,b))])
>>> [[1, 2, 3], [2, 3, 4]]
I would try something like this:
a = [[1,2,3],[2,3,4],[5,6,7],[7,8,9]]
b = [1,2]
result = [lst for lst in a if any(x in lst for x in b)]
A combination of list comprehension and sets would yield the wanted result. Note; I assume that repeated items and ordering is not of interest, if this is the case - a set won't work since it ignores ordering and only allows unique items.
A simple list comprehension would do, like below
filter_items = set(filter_items)
[sublist for sublist in original_list if not set(sublist).isdisjoint(filter_items)]
There's mainly one interesting part of this list comprehension, namely the if not set(sublist).isdisjoint(filter_items). Here you only keep the sublist if the set of sublist is not disjoint of the set filter_items i.e. none of the filter_items is in the sublist.
for your given example the provided answer would yield the following:
>>> a = [[1,2,3],[2,3,4],[5,6,7],[7,8,9]]
>>> b = set([1,2])
>>> [sublist for sublist in a if not set(sublist).isdisjoint(b)]
[[1, 2, 3], [2, 3, 4]]
Using a set approach the in can be mimic with an intersection:
a = [[1,2,3],[2,3,4],[5,6,7],[7,8,9]]
b = [1,2]
b_as_set = set(b)
out = [l for l in a if b_as_set.intersection(l)]
# [[1, 2, 3], [2, 3, 4]]
I would try something like this.
a = [[1,2,3],[2,3,4],[5,6,7],[7,8,9]]
b = [1,2]
print([lst for lst in a if any([item in b for item in lst])])

Remove list if it's contained in another list within the same nested list Python

I have a nested list:
regions = [[1,2,3],[3,4],[1,3,4],[1,2,3,5]]
I want to remove every list in this nested list which is contained in another one, i.e., [3,4] contained in [1,3,4] and [1,2,3] contained in [1,2,3,5], so the result is:
result = [[1,3,4],[1,2,3,5]]
So far I'm doing:
regions_remove = []
for i,reg_i in enumerate(regions):
for j,reg_j in enumerate(regions):
if j != i and list(set(reg_i)-set(reg_j)) == []:
regions_remove.append(reg_i)
regions = [list(item) for item in set(tuple(row) for row in regions) -
set(tuple(row) for row in regions_remove)]
And I've got: regions = [[1, 2, 3, 5], [1, 3, 4]] and this is a solution, but I'd like to know what's the most pythonic solution?
(sorry for not posting my entire code before, I'm a new to this...
Here is a solution with list comprehension and all() function :
nested_list = [[1,2,3],[3,4],[1,3,4],[1,2,3,5],[2,5]]
result = list(nested_list) #makes a copy of the initial list
for l1 in nested_list: #list in nested_list
rest = list(result) #makes a copy of the current result list
rest.remove(l1) #the list l1 will be compared to every other list (so except itself)
for l2 in rest: #list to compare
if all([elt in l2 for elt in l1]): result.remove(l1)
#if all the elements of l1 are in l2 (then all() gives True), it is removed
returns:
[[1, 3, 4], [1, 2, 3, 5]]
Further help
all() built-in function: https://docs.python.org/2/library/functions.html#all
copy a list: https://docs.python.org/2/library/functions.html#func-list
list comprehension: https://www.pythonforbeginners.com/basics/list-comprehensions-in-python
I'm definitely overlooking a simpler route, but this approach works
list comprehension
from itertools import product
l = [[1,2,3],[3,4],[1,3,4],[1,2,3,5]]
bad = [i for i in l for j in l if i != j if tuple(i) in product(j, repeat = len(i))]
final = [i for i in l if i not in bad]
Expanded explanation
from itertools import product
l = [[1,2,3],[3,4],[1,3,4],[1,2,3,5]]
bad = []
for i in l:
for j in l:
if i != j:
if tuple(i) in product(j, repeat = len(i)):
bad.append(i)
final = [i for i in l if i not in bad]
print(final)
[[1, 3, 4], [1, 2, 3, 5]]

Removing dupes in list of lists in Python

Basically, I'm trying to do remove any lists that begin with the same value. For example, two of the below begin with the number 1:
a = [[1,2],[1,0],[2,4],[3,5]]
Because the value 1 exists at the start of two of the lists -- I need to remove both so that the new list becomes:
b = [[2,4],[3,5]]
How can I do this?
I've tried the below, but the output is: [[1, 2], [2, 4], [3, 5]]
def unique_by_first_n(n, coll):
seen = set()
for item in coll:
compare = tuple(item[:n])
print compare # Keep only the first `n` elements in the set
if compare not in seen:
seen.add(compare)
yield item
a = [[1,2],[1,0],[2,4],[3,5]]
filtered_list = list(unique_by_first_n(1, a))
An efficient solution would be to create a Counter object to hold the occurrences of the first elements, and then filter the sub-lists in the main list:
from collections import Counter
counts = Counter(l[0] for l in a)
filtered = [l for l in a if counts[l[0]] == 1]
#[[2, 4], [3, 5]]
If you are happy to use a 3rd party library, you can use Pandas:
import pandas as pd
a = [[1,2],[1,0],[2,4],[3,5]]
df = pd.DataFrame(a)
b = df.drop_duplicates(subset=[0], keep=False).values.tolist()
print(b)
[[2, 4], [3, 5]]
The trick is the keep=False argument, described in the docs for pd.DataFrame.drop_duplicates.
You can use collections.Counter with list comprehension to get sublists whose first item appears only once:
from collections import Counter
c = Counter(n for n, _ in a)
b = [[x, y] for x, y in a if c[x] == 1]
Solution 1
a = [[1,2],[1,0],[2,4],[3,5]]
b = []
for item in a:
i = 0
if item[0] == a[i][0]:
i =+ 1
continue
else:
b.append(item)
i += 1
Solution 2
a = [[1,2],[1,0],[2,4],[3,5]]
b = []
for item in a:
for i in range(0, len(a)):
if item[0] == a[i][0]:
break
else:
if item in b:
continue
else:
b.append(item)
Output
(xenial)vash#localhost:~/pcc/10$ python3 remove_help.py
[[1, 2], [1, 0], [2, 4], [3, 5]]
[[2, 4], [3, 5]]
Achieved your goal no complex methods involed!
Enjoy!

remove characters from the first items in list of lists

I have a nested list and in every list the first item is a string that ends with .abc. I would like to remove all the .abc characters from my nested list.
Here's what I have got:
x = [['car.abc', 1, 2], ['ship.abc', 3, 4]]
And I would like to my nested list to be the following:
x = [['car', 1, 2], ['ship', 3, 4]]
How can I achieve this?
Using a simple for loop.
x = [['car.abc', 1, 2], ['ship.abc', 3, 4]]
for i in x:
i[0] = i[0].rsplit(".", 1)[0]
print(x)
Using nested regular expressions and list comprehension:
>>> import re
>>> [[re.sub(r'.abc$', '', e) if isinstance(e, basestring) else e for e in l] for l in x]
[['car', 1, 2], ['ship', 3, 4]]
isinstance(e, basestring) checks whether e is a string (see this question).
For a string e, re.sub(r'.abc$', '', e) replaces the part you specified
Otherwise e is untouched
The preceding happens for any element e in a list l, for each l in x.
Check online demo
x = [['car.abc', 1, 2], ['ship.abc', 3, 4]]
new_x=[]
for lst in x:
temp_lst=[]
for item in lst:
if(str(item)[-4:] == '.abc'):
item = str(item)[:-4]
temp_lst.append(item)
new_x.append(temp_lst)
print(new_x)

manipulating lists to find different variables

The following is the first line from my list l:
[0.0, 753.128, 990.43, 686.832, 366.922, -93.454, 1.0]
This is the result of:
print l[0]
I want to take all the first element from all such *lines of my list and assign them to another list. How can I do it in python?
Using a list comprehension:
lists = [[1,2,3], [4,5,6]]
[ l[0] for l in lists ]
That would do it. Nicer is to use map: you map a list of lists to a list of their heads:
map( lambda l: l[0], lists )
If performance is important, you may want to create an iterator over the heads of your lists:
heads = itertools.imap( lambda l: l[0], enumerate(lists))
for head in heads:
print head
Basic list comprehension:
another_list = [sublist[0] for sublist in l]
Try this:
a = [[1,2,3], ['a','b','c'], [True, False]]
first_elements = [e[0] for e in a]
print first_elements
>>> [1, 'a', True]
Something like this?
>>> a = [1, 2, 3, 4]
>>> b = [5,6,7,8]
>>> ab = [a, b]
>>> map (lambda x : x[0], ab)
[1, 5]
newlist=[]
for l in lst:
newlist.append(l[0])

Categories