Python, remove all numbers from sublist - python

I have the following list: [['F', 'G', 'C'], ['S', 3, 7], ['C', 3, 'D']] (made up of 3 sublists)
But I want to have: [['F', 'G', 'C'], ['S'], ['C', 'D']]
How would I go about doing this?

Use a list comprehension:
my_list = [['F', 'G', 'C'], ['S', 3, 7], ['C', 3, 'D']]
no_numbers = [[item for item in sub_list if not isinstance(item, int)]
for sub_list in my_list]
print(no_numbers)
This prints:
[['F', 'G', 'C'], ['S'], ['C', 'D']]

This is a code of Python 3:
mylist = [['F','G','C'], ['S',3,7], ['C',3,'D']]
rslist = [[y for y in x if not isinstance(y, int)] for x in mylist ]
print (rslist)

mylist = [['F', 'G', 'C'], ['S', 3, 7], ['C', 3, 'D']]
newlist = [[x for x in mysublist if not isinstance(x, int)] for mysublist in mylist]
print newlist
There are multiple ways to acheive this. The above example is using list comprehension.

Related

Replace elements in list based on a dictionary mapping table

I want to replace the elements in a list of lists based on a dictionary mapping table, and tried below:
lists_before = [['A', 'B', 'C'], ['A', 'D'], ['D', 'E']]
mapped_dictionary = {'A': 'G', 'B': 'G', 'C':'F'}
Below is the code I use:
lists_after = []
for element in lists_before:
new_element = []
for letter in element :
if letter in list(mapped_dictionary.values()):
letter = repl_dic.get(letter)
new_element.append(letter)
lists_after.append(new_element)
The output expected for lists_after is:
[['G', 'G', 'F'],['G','D'],['D','E']]
However, the output I got is still the same as lists_before.
I cannot figure out what went wrong. Could someone help me?
You can do it like this:
Input:
l = [['A', 'B', 'C'], ['A', 'D'], ['D', 'E']]
m = {'A': 'G', 'B': 'G', 'C': 'F'}
Code:
l_new = list()
for lst in l:
lst_new = list()
for ele in lst:
lst_new.append(m.get(ele, ele))
l_new.append(lst_new)
Output:
[['G', 'G', 'F'], ['G', 'D'], ['D', 'E']]
Or use a 1-liner:
[[m.get(ele, ele) for ele in lst] for lst in l]
[['G', 'G', 'F'], ['G', 'D'], ['D', 'E']]

Appending to a list of lists sequentially

I have two list of lists:
my_list = [[1,2,3,4], [5,6,7,8]]
my_list2 = [['a', 'b', 'c'], ['d', 'e', 'f']]
I want my output to look like this:
my_list = [[1,2,3,4,'a','b','c'], [5,6,7,8,'d','e','f']]
I wrote the following code to do this but I end up getting more lists in my result.
my_list = map(list, (zip(my_list, my_list2)))
this produces the result as:
[[[1, 2, 3, 4], ['a', 'b', 'c']], [[5, 6, 7, 8], ['d', 'e', 'f']]]
Is there a way that I can remove the redundant lists.
Thanks
Using zip is the right approach. You just need to add the elements from the tuples zip produces.
>>> my_list = [[1,2,3,4], [5,6,7,8]]
>>> my_list2 = [['a', 'b', 'c'], ['d', 'e', 'f']]
>>> [x+y for x,y in zip(my_list, my_list2)]
[[1, 2, 3, 4, 'a', 'b', 'c'], [5, 6, 7, 8, 'd', 'e', 'f']]
You can use zip in a list comprehension:
my_list = [[1,2,3,4], [5,6,7,8]]
my_list2 = [['a', 'b', 'c'], ['d', 'e', 'f']]
new_list = [i+b for i, b in zip(my_list, my_list2)]
As an alternative you may also use map with sum and lambda function to achieve this (but list comprehension approach as mentioned in other answer is better):
>>> map(lambda x: sum(x, []), zip(my_list, my_list2))
[[1, 2, 3, 4, 'a', 'b', 'c'], [5, 6, 7, 8, 'd', 'e', 'f']]

delete items from list of list: pythonic way

I've this kind of list of list (only two nested level):
my_list = [['A'], ['B'], ['C','D','A','B'], ['E'], ['B', 'F', 'G'], ['H']]
I've a list of items to delete in my_list:
to_del = ['A','B']
this is my idea of code to delete to_del elements from my_list:
for i in my_list:
for d in to_del:
if d in i:
i.remove(d)
Output:
[[], [], ['C', 'D'], ['E'], ['F', 'G'], ['H']]
Here my questions:
Can you suggest a more pythonic/elegant way to do the same
Can you suggest a smart way to generalize the number of nested levels
e.g my_list = [ ['A'], ['B'], ['C', ['D', 'E', ['F']], 'G'], ['H'] ]
The ideal method will have a boolean argument empty_lists to decide whether or not keep empty lists.
Try list comprehension:
my_list = [[x for x in sublist if x not in to_del] for sublist in my_list]
Output:
>>> my_list
[[], [], ['C', 'D'], ['E'], ['F', 'G'], ['H']]
With nested list comprehensions:
[[y for y in x if y not in to_del] for x in my_list]
With list comprehension and lambda filter:
[filter(lambda y: y not in to_del, x) for x in my_list]
An attempt for the general case of arbitrarily nested lists:
def f(e):
if not isinstance(e,list):
if e not in to_del:
return e
else:
return filter(None,[f(y) for y in e])
to_del = ['A','B']
my_list= [['A'], ['B',['A','Z', ['C','Z','A']]], ['C','D','A','B'],['E'], ['B','F','G'], ['H']]
>>> f(my_list)
[[['Z', ['C', 'Z']]], ['C', 'D'], ['E'], ['F', 'G'], ['H']]

split list in sub lists by number of elements

In python, if I have the list of elements
l = ['a', 'b', 'c', 'd', 'e', 'f']
and a list of numbers
n = [2, 1, 3]
How I can split the list l by the numbers in n ?
And get this list of lists
[['a', 'b'], ['c'], ['d', 'e', 'f']]
You could use islice:
>>> from itertools import islice
>>> l = ['a', 'b', 'c', 'd', 'e', 'f']
>>> n = [2, 1, 3]
>>> it = iter(l)
>>> out = [list(islice(it, size)) for size in n]
>>> out
[['a', 'b'], ['c'], ['d', 'e', 'f']]
It's a bit obfuscated, but still:
ll = [[l.pop(0) for _ in range(k)] for k in n]
Note that this traversal will not leave the list intact because of the pop() thingy.
You can create an iterator out of the list. Then call next the appropriate number of times.
>>> l = ['a', 'b', 'c', 'd', 'e', 'f']
>>> n = [2, 1, 3]
>>> it = iter(l)
>>> [[next(it) for i in xrange(k)] for k in n]
[['a', 'b'], ['c'], ['d', 'e', 'f']]
Yet another way
if __name__ == '__main__':
l = ['a', 'b', 'c', 'd', 'e', 'f']
n = [2, 1, 3]
result = []
for i in n:
j = l[:i]
result.append(j)
l = l[i:]
print result
Gives
[['a', 'b'], ['c'], ['d', 'e', 'f']]
It's not as short as some other solutions, but it sure as hell is readable
cuts = [sum(n[:i]) for i in range(len(n) + 1)]
>>> [l[cuts[i]:cuts[i + 1]] for i in range(len(cuts) - 1)]
[['a', 'b'], ['c'], ['d', 'e', 'f']]
This leaves the list intact:
>>> l
['a', 'b', 'c', 'd', 'e', 'f']
I think this would be most optimized as it will only required len(n) number of iterations.
l = ['a', 'b', 'c', 'd', 'e', 'f']
n = [2, 1, 3]
res = []
temp = 0
for i in n:
res.append(l[temp:temp+i])
temp = temp+i
print res
Returns:
[['a', 'b'], ['c'], ['d', 'e', 'f']]
You can use numpy.split :
>>> np.split(l,[sum(n[:i]) for i in range(len(n))])
[array([], dtype=float64), array(['a', 'b'],
dtype='|S1'), array(['c'],
dtype='|S1'), array(['d', 'e', 'f'],
dtype='|S1')]

append list of values to sublists

How do you append each item of one list to each sublist of another list?
a = [['a','b','c'],['d','e','f'],['g','h','i']]
b = [1,2,3]
Result should be:
[['a','b','c',1],['d','e','f',2],['g','h','i',3]]
Keep in mind that I want to do this to a very large list, so efficiency and speed is important.
I've tried:
for sublist,value in a,b:
sublist.append(value)
it returns 'ValueError: too many values to unpack'
Perhaps a listindex or a listiterator could work, but not sure how to apply here
a = [['a','b','c'],['d','e','f'],['g','h','i']]
b = [1,2,3]
for ele_a, ele_b in zip(a, b):
ele_a.append(ele_b)
Result:
>>> a
[['a', 'b', 'c', 1], ['d', 'e', 'f', 2], ['g', 'h', 'i', 3]]
The reason your original solution did not work, is that a,b does create a tuple, but not what you want.
>>> z = a,b
>>> type(z)
<type 'tuple'>
>>> z
([['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']], [1, 2, 3])
>>> len(z[0])
3
>>> for ele in z:
... print ele
...
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']] #In your original code, you are
[1, 2, 3] #unpacking a list of 3 elements
#into two values, hence the
#'ValueError: too many values to unpack'
>>> zip(a,b) # using zip gives you what you want.
[(['a', 'b', 'c'], 1), (['d', 'e', 'f'], 2), (['g', 'h', 'i'], 3)]
Here is a simple solution:
a = [['a','b','c'],['d','e','f'],['g','h','i']]
b = [1,2,3]
for i in range(len(a)):
a[i].append(b[i])
print(a)
One option, using list comprehension:
a = [(a[i] + b[i]) for i in range(len(a))]
Just loop through the sublists, adding one item at a time:
for i in range(0,len(listA)):
listA.append(listB[i])
You can do:
>>> a = [['a','b','c'],['d','e','f'],['g','h','i']]
>>> b = [1,2,3]
>>> [l1+[l2] for l1, l2 in zip(a,b)]
[['a', 'b', 'c', 1], ['d', 'e', 'f', 2], ['g', 'h', 'i', 3]]
You can also abuse a side effect of list comprehensions to get this done in place:
>>> [l1.append(l2) for l1, l2 in zip(a,b)]
[None, None, None]
>>> a
[['a', 'b', 'c', 1], ['d', 'e', 'f', 2], ['g', 'h', 'i', 3]]

Categories

Resources