I have 2 list of lists.
One is say list1, which is :
[['1', '2', '*', '2', '1', '0.8'],
['1', '2', '3', '1', '1', '0.7'],
['*', '*', '3', '4', '1', '0.5'],
['1', '2', '*', '1', '1', '0.3'],
['2', '2', '*', '2', '1', '0.1']]
And list2 is :
[['3', '*', '1', '4', '1', '0.9'],
['1', '2', '2', '2', '1', '0.4'],
['2', '2', '*', '2', '1', '0.1']]
Now I want to get the union of these 2 list of lists and create a 3rd list of list and as ['2', '2', '*', '2', '1', '0.1'] this list is there in both of them so I want this to be in the final list of list for only 1 time.
I am doing:
final_list=list1 + list2
Final list is producing :
[['3', '*', '1', '4', '1', '0.9'],
['1', '2', '*', '2', '1', '0.8'],
['1', '2', '3', '1', '1', '0.7'],
['*', '*', '3', '4', '1', '0.5'],
['1', '2', '2', '2', '1', '0.4'],
['1', '2', '*', '1', '1', '0.3'],
['2', '2', '*', '2', '1', '0.1'],
['2', '2', '*', '2', '1', '0.1']]
My desired outcome is :
[['3', '*', '1', '4', '1', '0.9'],
['1', '2', '*', '2', '1', '0.8'],
['1', '2', '3', '1', '1', '0.7'],
['*', '*', '3', '4', '1', '0.5'],
['1', '2', '2', '2', '1', '0.4'],
['1', '2', '*', '1', '1', '0.3'],
['2', '2', '*', '2', '1', '0.1']]
If you don't care about order, you can convert them to sets and union (|) them:
list1 = [['1', '2', '*', '2', '1', '0.8'], ['1', '2', '3', '1', '1', '0.7'], ['*', '*', '3', '4', '1', '0.5'], ['1', '2', '*', '1', '1', '0.3'], ['2', '2', '*', '2', '1', '0.1']]
list2 = [['3', '*', '1', '4', '1', '0.9'], ['1', '2', '2', '2', '1', '0.4'], ['2', '2', '*', '2', '1', '0.1']]
output = set(map(tuple, list1)) | set(map(tuple, list2))
print(output)
# {('1', '2', '*', '1', '1', '0.3'),
# ('2', '2', '*', '2', '1', '0.1'),
# ('1', '2', '3', '1', '1', '0.7'),
# ('1', '2', '*', '2', '1', '0.8'),
# ('3', '*', '1', '4', '1', '0.9'),
# ('1', '2', '2', '2', '1', '0.4'),
# ('*', '*', '3', '4', '1', '0.5')}
If you want to have a list of lists (instead of a set of tuples), add the following:
output = list(map(list, output))
While this has been answered, here's a pretty simple way of doing it creating a third list and only appending elements to the third list if the element doesn't exist yet.
>>> results = []
>>> for sublist in list1 + list2:
... if sublist not in results:
... results.append(sublist)
...
>>> pp(results)
[['1', '2', '*', '2', '1', '0.8'],
['1', '2', '3', '1', '1', '0.7'],
['*', '*', '3', '4', '1', '0.5'],
['1', '2', '*', '1', '1', '0.3'],
['2', '2', '*', '2', '1', '0.1'],
['3', '*', '1', '4', '1', '0.9'],
['1', '2', '2', '2', '1', '0.4']]
>>>
You should be able to create a set, add each element of each list to that set, then create a list from that set, something like:
new_set = set()
for item in list1:
set.add(item)
for item in list2:
set.add(item)
final_list = list(set)
It won't be guaranteed to be in order but it will have only unique elements. Of course, if you don't care about order, you may as well be using sets exclusively so you don't have to concern yourself with duplicates.
If you want to maintain order, you just maintain both a final list and the set, and only add to the final list if it's not already in the set:
dupe_set = set()
final_list = []
for item in list1:
if item not in dupe_set:
set.add(item)
final_list.append(item)
for item in list1:
if item not in dupe_set:
set.add(item)
final_list.append(item)
Whatever method you choose, this is the sort of thing that cries out for a function/method to do the heavy lifting, since it's quite likely you may want to do this more than once in your code (sometimes, it's worth a separate method even if only done once, as that can aid readability).
For example, these are the equivalent methods for the two options shown above, able to handle any number of input lists:
# Call with x = join_lists_uniq_any_order([list1, list2, ...])
def join_lists_uniq_any_order(list_of_lists):
# Process each list, adding each item to (initially empty) set.
new_set = set()
for one_list in list_of_lists:
for item in one_list:
set.add(item)
return list(set)
# Call with x = join_lists_uniq_keep_order([list1, list2, ...])
def join_lists_uniq_keep_order(list_of_lists):
dupe_set = set()
final_list = []
# Process each list, adding each item if not yet seen.
for one_list in list_of_lists:
for item in one_list:
if item not in dupe_set:
set.add(item)
final_list.append(item)
Related
A = [['0', '6', '4', '3'], ['0', '2', '8', '3'], ['0', '4', '1', '5'], ['0', '3', '2', '5']]
B = ['0', '4', '1', '5']
Say I want to find out at which line does B equal to the list. How do I write a solution for this?
The answer would be the third line.
I tried doing a for loop.
You can try list.index(element) to get the index of the element in the original list (A). In your terminology, to get the line just add one to the index.
line = A.index(B) + 1
you dont need use loops.you can get the element index by indexing.
A = [['0', '6', '4', '3'], ['0', '2', '8', '3'], ['0', '4', '1', '5'], ['0', '3', '2', '5']]
B = ['0', '4', '1', '5']
print(A.index(B))
>>> 2
After a lengthy operation I get a defaultdict like the following:
l = defaultdict(list)
l = [('S', ['(', 'Num']), ('Num',['Sign', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']), ('Op', ['+', '-', '*', '/']), ('Sign', ['-'])]
print(l)
How can I now update all values for each key if they have values from another key?
Expected result:
Step 1:
l_new = [('S', ['(', 'Sign', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']), ('Num',['-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']), ('Op', ['+', '-', '*', '/']), ('Sign', ['-'])]
print(l)
Step 2:
l_new = [('S', ['(', '-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']), ('Num',['-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']), ('Op', ['+', '-', '*', '/']), ('Sign', ['-'])]
print(l)
You can use a one-liner like so:
l = dict([('S', ['(', 'Num']), ('Num',['Sign', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']), ('Op', ['+', '-', '*', '/']), ('Sign', ['-'])])
l_new = {
k: [val for subl in (l.get(el, [el]) for el in v) for val in subl]
for k, v in l.items()
}
print(l_new)
# {'S': ['(', 'Sign', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
# 'Num': ['-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
# 'Op': ['+', '-', '*', '/'],
# 'Sign': ['-']}
If you need to repeat the operation more than once, then just run it again. (Reassign to l and compute another l_new.)
You can use a recursive generator function:
l = [('S', ['(', 'Num']), ('Num',['Sign', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']), ('Op', ['+', '-', '*', '/']), ('Sign', ['-'])]
l_d = dict(l) #convert l to a dictionary for faster lookup
def get_keys(d, c = []):
if d not in l_d:
yield d
elif d not in c:
yield from [i for k in l_d[d] for i in get_keys(k, c+[d])]
r = [(a, [j for k in b for j in get_keys(k)]) for a, b in l]
Output:
[('S', ['(', '-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']), ('Num', ['-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']), ('Op', ['+', '-', '*', '/']), ('Sign', ['-'])]
With recursion, you do not need to manually run a single comprehension multiple times to replace key tokens in value lists of l, as it will continue to traverse l, replacing the key tokens with their subsequent non-key tokens.
gene=[]
x=1
path = '/content/drive/MyDrive/abc.txt'
file = open(path,'r').readlines()
for i in file[x]:
i.split('\t')[0]
gene.append(i)
x+=1
print(gene)
my output is
['A', 'H', 'Y', '3', '9', '2', '7', '8', '\t', '1', '4', '5', '.', '5', '4', '4', '\t', '1', '3', '5', '.', '2', '4', '\t', '5', '6', '.', '5', '1', '3', '8']
but i want it to split at '/t', taking the first element in the list which is AHY392978 and append it into the list gene
['AHY39278', 'AHY39278']
any idea how to join the elements together?
add this code to your project:
string = ''
for(i in range len(gene)):
string += gene[i]
you can get your data from string
I have a list like the one below and I would like to delete all entries between any word (inclusive) and the next '0' (exclusive).
So for example this list:
array = ['1', '1', '0', '3', '0', '2', 'Continue', '1', '5', '1', '4', '0', '7', 'test', '3', '6', '0']
should become:
['1', '1', '0', '3', '0', '2', '0', '7', '0']
You can also do it by using exclusively list comprehension:
array = ['1', '1', '0', '3', '0', '2', 'Continue', '1', '5', '1', '4', '0', '7', 'test', '3', '6', '0']
# Find indices of strings in list
alphaIndex = [i for i in range(len(array)) if any(k.isalpha() for k in array[i])]
# Find indices of first zero following each string
zeroIndex = [array.index('0',i) for i in alphaIndex]
# Create a list with indices to be `blacklisted`
zippedIndex = [k for i,j in zip(alphaIndex, zeroIndex) for k in range(i,j)]
# Filter the original list
array = [i for j,i in enumerate(array) if j not in zippedIndex]
print(array)
Output:
['1', '1', '0', '3', '0', '2', '0', '7', '0']
array = ['1', '1', '0', '3', '0', '2', 'Continue', '1', '5', '1', '4', '0', '7', 'test', '3', '6', '0']
res = []
skip = False #Flag to skip elements after a word
for i in array:
if not skip:
if i.isalpha(): #Check if element is alpha
skip = True
continue
else:
res.append(i)
else:
if i.isdigit(): #Check if element is digit
if i == '0':
res.append(i)
skip = False
print res
Output:
['1', '1', '0', '3', '0', '2', '0', '7', '0']
Kicking it old school -
array = ['1', '1', '0', '3', '0', '2', 'Continue', '1', '5', '1', '4', '0', '7', 'test', '3', '6', '0']
print(array)
array_op = []
i=0
while i < len(array):
if not array[i].isdigit():
i = array[i:].index('0')+i
continue
array_op.append(array[i])
i += 1
print(array_op)
I am trying to get all possible pattern from list like:
input_x = ['1', ['2', '2x'], '3', '4', ['5', '5x']]
As we see, it has 2 nested list ['2', '2x'] and ['5', '5x'] here.
That means all possible pattern is 4 (2 case x 2 case), the expect output is:
output1 = ['1','2' , '3', '4', '5']
output2 = ['1','2x', '3', '4', '5']
output3 = ['1','2' , '3', '4', '5x']
output4 = ['1','2x', '3', '4', '5x']
I tried to search how to, but I can not find any examples (because of I have no idea about "keyword" to search)
I think python has inner libraries/methods to handle it.
One way to achieve this is via using itertools.product. But for using that, you need to firstly wrap the single elements within your list to another list.
For example, firstly we need to convert your list:
['1', ['2', '2x'], '3', '4', ['5', '5x']]
to:
[['1'], ['2', '2x'], ['3'], ['4'], ['5', '5x']]
This can be done via below list comprehension as:
formatted_list = [(l if isinstance(l, list) else [l]) for l in my_list]
# Here `formatted_list` is containing the elements in your desired format, i.e.:
# [['1'], ['2', '2x'], ['3'], ['4'], ['5', '5x']]
Now call itertools.product on the unpacked version of the above list:
>>> from itertools import product
# v `*` is used to unpack the `formatted_list` list
>>> list(product(*formatted_list))
[('1', '2', '3', '4', '5'), ('1', '2', '3', '4', '5x'), ('1', '2x', '3', '4', '5'), ('1', '2x', '3', '4', '5x')]
If you don't want to convert your list to all sub list then
You can try something like this :
input_x = ['1', ['2', '2x'], '3', '4', ['5', '5x'],['6','6x']]
import itertools
non_li=[]
li=[]
for i in input_x:
if isinstance(i,list):
li.append(i)
else:
non_li.append(i)
for i in itertools.product(*li):
sub=non_li[:]
sub.extend(i)
print(sorted(sub))
output:
['1', '2', '3', '4', '5', '6']
['1', '2', '3', '4', '5', '6x']
['1', '2', '3', '4', '5x', '6']
['1', '2', '3', '4', '5x', '6x']
['1', '2x', '3', '4', '5', '6']
['1', '2x', '3', '4', '5', '6x']
['1', '2x', '3', '4', '5x', '6']
['1', '2x', '3', '4', '5x', '6x']