How to Check if Element exists in Second Sublist? - python

If I had a list like this:
L = [
['a', 'b'],
['c', 'f'],
['d', 'e']
]
I know that I could check if e.g. 'f' was contained in any of the sub lists by using any in the following way:
if any('f' in sublist for sublist in L) # True
But how would I go about searching through second sub lists, i.e. if the list was initialized the following way:
L = [
[
['a', 'b'],
['c', 'f'],
['d', 'e']
],
[
['z', 'i', 'l'],
['k']
]
]
I tried chaining the for in expressions like this:
if any('f' in second_sublist for second_sublist in sublist for sublist in L)
However, this crashes because name 'sublist' is not defined.

First write your logic as a regular for loop:
for first_sub in L:
for second_sub in first_sub:
if 'f' in second_sub:
print('Match!')
break
Then rewrite as a generator expression with the for statements in the same order:
any('f' in second_sub for first_sub in L for second_sub in first_sub)

If you don't need to know where 'f' is located you can leverage itertools here as well.
import itertools
any('f' in x for x in itertools.chain.from_iterable(l))
This will flatten your nested lists and evaluate each list separately. The benefit here is if you have three nested lists this solution would still function without having to continue writing nest for loops.

Related

Joining values of a list inside another list into a string

Im trying to join the letters as a string that's inside the list which is also inside the list. So for example, it looks like this [['a', 'b', 'c'], ['d', 'e', 'f']] however I want the result to look like 'ad be cf' which is basically taking the element that lies in the same position in the list. I know how to join the elements into a list that can look like 'abcdef', however, i don't know which I could add in order to return a string that looks like above.
Any advice would be thankful!
string = ''
new_grid = []
for a in grid:
for b in a:
string += b
return string
When you want to transpose lists into columns, you typically reach for zip(). For example:
l = [['a', 'b', 'c'], ['d', 'e', 'f']]
# make a list of columns
substrings = ["".join(sub) for sub in zip(*l)]
#['ad', 'be', 'cf']
print(" ".join(substrings))
# alternatively print(*substrings, sep=" ")
# ad be cf
This works:
my_list = [['a', 'b', 'c'], ['d', 'e', 'f']]
sorted_list = [list(pair) for pair in zip(my_list[0], my_list[1])]
for i in range(3):
string = ''.join(sorted_list[i])
print(string, end=" ")
First, we are pairing each individual list to its corresponding value using [zip][1], then we are joining it into a string, and printing it out.
This solution may not be the most efficient, but it's simple to understand.
Another quick solution without zip could look like this:
my_list = [['a', 'b', 'c'], ['d', 'e', 'f']]
sorted_list = list(map(lambda a, b: a + b, my_list[0], my_list[1]))
print(" ".join(sorted_list))

Alternative to using the sort function when adding to a list?

I want to insert a word alphabetically into a list. Originally I would append the word I'm adding to the end of the list and then sort the list, but I am not allowed to use the sort() function.
Is there a way to do this through a function?
Based of of #SheshankS.'s answer. A function to do this for you:
def insert(item, _list):
for index, element in enumerate(_list):
if item < element: # in python, this automatically compares alphabetical precedence.
_list.insert(index, item)
return # exit out of the function since we already inserted
# if the item was not inserted, it must have the lowest precedence, so just append it
_list.append(item)
Note that since lists are mutable, this will actually mutate the given instance.
So, this:
someList = ["a", "b", "d"]
insert("c", someList)
Will actually change someList instead of just returning the new value.
Try doing this:
array = ["asdf", "bsdf", "kkkk", "zssdd"]
insertion_string = "zzat"
i = 0
for element in array:
if insertion_string < element:
array.insert(i, insertion_string)
break
i += 1
# if it is last one
if not insertion_string in array:
array.append(insertion_string)
print (array )
Repl.it = https://repl.it/repls/VitalAvariciousCodec
You did not say if you are allowed to use third-party modules, and you did not say if speed is a factor. If you want to add a new item to your sorted list quickly and you are allowed to use a module, use the SortedList class from sortedcontainers. This is a module included in many distributions of Python, such as Anaconda.
This will be simple and fast, even for large lists.
someList = SortedList(["a", "b", "d"])
someList.add("c")
print(someList)
The printout from that is
SortedList(['a', 'b', 'c', 'd'])
>>> import bisect
>>> someList = ["a", "b", "d"]
>>> bisect.insort(someList,'c')
>>> someList
['a', 'b', 'c', 'd']
>>>
If standard lib is allowed you can use bisect:
>>> import bisect
>>> lst = list('abcefg')
>>> for x in 'Adh':
... lst.insert(bisect.bisect(lst, x), x)
... print(lst)
...
['A', 'a', 'b', 'c', 'e', 'f', 'g']
['A', 'a', 'b', 'c', 'd', 'e', 'f', 'g']
['A', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

Remove duplicate elements in python

for a given list for example:
[
'A',
[
'B',
['D','C'],
['C','D']
],
['C','D'],
['E','F'],
['F','E'],
[
['not','M'],
'N',
['not','M']
]
]
I want to remove the duplicate element in it, the result of the above list should be:
[
'A',
[
'B',
['C','D']
],
['C','D'],
['E','F'],
[
['not','M'],
'N'
]
]
It has two rules: ['not','A'] represents ~A, and it can be seen as one element.
If the value is same but order not, we consider it the same.So ['C','D'] is same as ['D','C']
Can anyone one help me write this function in python to realize the requirement?
In general, I agree with Klaus D.'s comment. But I thought the question was interesting since the easiest way I could think of was using lists->tuples->sets and that gets kind of interesting when you want to remove elements. It also causes you to lose the ordering of the original input list (As noted by Adam Smith).
So given all that, consider:
import itertools
def _reduce(lst):
if not isinstance(lst, list): return lst
seen = []
for x in lst:
if not any(list(perm) in seen for perm in itertools.permutations(x)):
seen.append(_reduce(x))
return seen
Which you can run by:
lst = [
'A',
[
'B',
['D','C'],
['C','D']
],
['C','D'],
['E','F'],
['F','E'],
[
['not','M'],
'N',
['not','M']
]
]
print _reduce(lst)
Which outputs:
[
'A',
[
'B',
['D', 'C']
],
['C', 'D'],
['E', 'F'],
[
['not', 'M'],
'N'
]
]
Note that this preserves input ordering of list elements. Also note, that because of this, this output differs slightly from your expected output (['D', 'C'] is preserved and ['C', 'D'] is discarded).
Edit Per your commment, itertools.permutations() won't suffice, since you seem to want some recursive function that will consider the permutations of the subelements as well. What about:
import itertools
def _permutations(x):
if not isinstance(x, list): return x
perms = []
for prod in itertools.product(*[_permutations(elem) for elem in x]):
for perm in itertools.permutations(prod):
perms.append(list(perm))
return perms
def _reduce(lst):
if not isinstance(lst, list): return lst
seen = []
for x in lst:
if not any(list(perm) in seen for perm in _permutations(x)):
seen.append(_reduce(x))
return seen
def lexsort(x): return sorted(str(e) for e in _permutations(x))
arrs = [
['B',['C','D']],
[['D','C'],'B'],
]
print _reduce(arrs)
Outputs:
[['B', ['C', 'D']]]

search an item of sublist in another list of list by position

I have a list of list created like
biglist=[['A'], ['C', 'T'], ['A', 'T']]
and I will have another list like
smalllist=[['C'], ['T'], ['A', 'T']]
So, I want to check wheter an item in small list contains in that specific index of biglist, if not append to it.
so, making
biglist=[['A','C'], ['C', 'T'], ['A', 'T']]
so, 'C' from fist sublist of smalllist was added to first sublist of biglist. but not for second and third.
I tried like
dd=zip(biglist, smalllist)
for each in dd:
ll=each[0].extend(each[1])
templist.append(list(set(ll)))
but get errors
templist.append(list(set(ll)))
TypeError: 'NoneType' object is not iterable
How to do it?
Thank you
Probably, you should try this:
// This will only work, if smalllist is shorter than biglist
SCRIPT:
biglist = [['A'], ['C', 'T'], ['A', 'T']]
smalllist = [['C'], ['T'], ['A', 'T']]
for i, group in enumerate(smalllist):
for item in group:
if item not in biglist[i]:
biglist[i].append(item)
DEMO:
print(biglist)
# [['A', 'C'], ['C', 'T'], ['A', 'T']]
[list(set(s+b)) for (s,b) in zip(smalllist,biglist)]
For some reason, extend in Python doesn't return the list itself after extending. So ll in your case is None. Just put ll=each[0] on the second line in the loop, and your solution should start working.
Still, I'm not getting, why you don' keep your elements in sets in the first place. This would avoid you from having to convert from list to set and then backwards.
I would just or sets instead of appending to the list and then filtering out duplicates by resorting to set and then to list.
>>> from itertools import izip
>>> templist = []
>>> for els1,els2 in izip(biglist,smalllist):
joined = list(set(els1) | set(els2))
templist.append(joined)
>>> templist
[['A', 'C'], ['C', 'T'], ['A', 'T']]
Keeping elements in sets in the first place seems to be the fastest in Python 3 even for such small amount of elements in each set (see comments):
biglist=[set(['A']), set(['C', 'T']), set(['A', 'T'])]
smalllist=[set(['C']), set(['T']), set(['A', 'T'])]
for els1,els2 in zip(biglist,smalllist):
els1.update(els2)
print(biglist)
Ouput:
[{'A', 'C'}, {'C', 'T'}, {'A', 'T'}]

Combining elements in list using python

Given input:
list = [['a']['a', 'c']['d']]
Expected Ouput:
mylist = a,c,d
Tried various possible ways, but the error recieved is TypeError: list indices must be integers not tuple.
Tried:
1.
k= []
list = [['a']['a', 'c']['d']]
#k=str(list)
for item in list:
k+=item
print k
2.
print zip(*list)
etc.
Also to strip the opening and closing parenthesis.
What you want is flattening a list.
>>> import itertools
>>> l
[['a'], ['a', 'c'], ['d']]
>>> res = list(itertools.chain.from_iterable(l))
>>> res
['a', 'a', 'c', 'd']
>>> set(res) #for uniqify, but doesn't preserve order
{'a', 'c', 'd'}
Edit: And your problem is, when defining a list, you should seperate values with a comma. So, not:
list = [['a']['a', 'c']['d']]
Use commas:
list = [['a'], ['a', 'c'], ['d']]
And also, using list as a variable is a bad idea, it conflicts with builtin list type.
And, if you want to use a for loop:
l = [['a'], ['a', 'c'], ['d']]
k = []
for sublist in l:
for item in sublist:
if item not in k: #if you want list to be unique.
k.append(item)
But using itertools.chain is better idea and more pythonic I think.
While utdemir's answer does the job efficiently, I think you should read this - start from "11.6. Recursion".
The first examples deals with a similar problem, so you'll see how to deal with these kinds of problems using the basic tools.

Categories

Resources