This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 3 years ago.
How can I remove from a list of list every list in which a '5' is placed before a '3' given an initial list of list like the following one?
[('3', '3', '3'), ('3', '3', '5'), ('3', '5', '3'), ('3', '5', '5'), ('5', '3', '3'), ('5', '3', '5'), ('5', '5', '3'), ('5', '5', '5')]
I tried with
for i in list_ck:
for j in range(0,2):
if (i[j]=='5' and i[j+1]=='3'):
list_ck.remove(i)
but it doesn't work
It's easier to test whether a 5 occurs before a 3 if they are strings, rather than tuples; so we can use ''.join to convert them to strings.
>>> data = [('3', '3', '3'), ('3', '3', '5'), ('3', '5', '3'), ('3', '5', '5'), ('5', '3', '3'), ('5', '3', '5'), ('5', '5', '3'), ('5', '5', '5')]
>>> [r for r in data if '53' not in ''.join(r)]
[('3', '3', '3'), ('3', '3', '5'), ('3', '5', '5'), ('5', '5', '5')]
This assumes you only want to test for a 5 immediately before a 3, and won't work for more general cases where the strings in the tuple could e.g. be '53' themselves. But it's sufficient for your example.
A more general solution is to use a regex, and join on a character like , which none of the strings will contain:
>>> data = [('5', '3', '1'), ('53', '1', '1'), ('5', '1', '3')]
>>> import re
>>> pattern = re.compile('(^|,)5,(.*,)*3(,|$)')
>>> [r for r in data if not pattern.search(','.join(r))]
[('53', '1', '1')]
Here the pattern (^|,)5,(.+,)*3(,|$) matches a 5 either at the start or after a ,, followed by a comma, followed by any number of things ending with commas, followed by a 3 which is either before a comma or the end of the string.
You could use a conditional list comprehension:
# List of Tuples (lot).
list_of_tups = [('3', '3', '3'), ('3', '3', '5'), ('3', '5', '3'), ('3', '5', '5'), ('5', '3', '3'), ('5', '3', '5'), ('5', '5', '3'), ('5', '5', '5')]
>>> [tup for tup in list_of_tups
if not any((a == '5' and b == '3') for a, b in zip(tup, tup[1:]))]
[('3', '3', '3'), ('3', '3', '5'), ('3', '5', '5'), ('5', '5', '5')]
To modify the list inplace rather than create a new list, create an index of items that need to be removed and then pop them off in reverse order.
idx = [n for n, tup in enumerate(list_of_tups)
if any((a == '5' and b == '3') for a, b in zip(tup, tup[1:]))]
for i in reversed(idx):
list_of_tups.pop(i)
>>> list_of_tups
[('3', '3', '3'), ('3', '3', '5'), ('3', '5', '5'), ('5', '5', '5')]
Try to create another list with the same arguments (dont copy them, create new) and remove() from the second list
tab = [('3', '3', '3'), ('3', '3', '5'), ('3', '5', '3'), ('3', '5', '5'), ('5', '3', '3'), ('5', '3', '5'), ('5', '5', '3'), ('5', '5', '5')]
tab2 = [('3', '3', '3'), ('3', '3', '5'), ('3', '5', '3'), ('3', '5', '5'), ('5', '3', '3'), ('5', '3', '5'), ('5', '5', '3'), ('5', '5', '5')]
for i in tab:
for j in range(0,2):
if i[j]=='5' and i[j+1]=='3':
tab2.remove(i)
break
I was working on some other question . I have below list
[(['1', '2', '3'], 'abc'), (['4', '5', '6'], 'xyz')]
Output should be below
[('1', 'abc'), ('2', 'abc'), ('3', 'abc'), ('4', 'xyz'), ('5', 'xyz'), ('6', 'xyz')]
My attempt is
First i unlist the list inside it
l1=[ tuple(i[0])+(i[1],) for i in l ]
print (l1)
[('1', '2', '3', 'abc'), ('4', '5', '6', 'xyz')]
Then tried product from itertools , but it is not giving me the required result. Problem is 'abc' is getting splited in 'a','b','c' using product.
from itertools import product
[ list(product(i[:-1],i[-1])) for i in l1 ]
[[('1', 'a'),
('1', 'b'),
('1', 'c'),
('2', 'a'),
('2', 'b'),
('2', 'c'),
('3', 'a'),
('3', 'b'),
('3', 'c')],
[('4', 'x'),
('4', 'y'),
('4', 'z'),
('5', 'x'),
('5', 'y'),
('5', 'z'),
('6', 'x'),
('6', 'y'),
('6', 'z')]]
Use list comprehension:
L=[(['1', '2', '3'], 'abc'), (['4', '5', '6'], 'xyz')]
In: [ (n,s) for l,s in L for n in l ]
Out:
[('1', 'abc'),
('2', 'abc'),
('3', 'abc'),
('4', 'xyz'),
('5', 'xyz'),
('6', 'xyz')]
As you can write:
rslt=[]
for l,s in L:
for n in l:
rslt.append((n,s))
product from itertools is working as intended. The issue is that Python strings are iterable, so product is iterating through the elements of the string. If you want to treat the string as a single element, you can put it into a list and feed the list to product
You can use itertools.product as long as you wrap the string in an iterable so that it is handled as a single element of an iterable rather than iterated.
from itertools import product
data = [(['1', '2', '3'], 'abc'), (['4', '5', '6'], 'xyz')]
combos = [combo for a, b in data for combo in product(a, [b])]
print(combos)
# [('1', 'abc'), ('2', 'abc'), ('3', 'abc'), ('4', 'xyz'), ('5', 'xyz'), ('6', 'xyz')]
You can use list comprehensions:
ls = [(['1', '2', '3'], 'abc'), (['4', '5', '6'], 'xyz')]
ls_new = [(a,b) for n,b in ls for a in n]
print(ls_new)
I have a list like this. last_1=[['3', '3', '2', 'F', '2', 'C', '2', 'D', '2', 'A', '2', '8', '7', 'C', '3', 'B', '2', 'E', '2', 'E', '3', '3', '3', '4', '3', '3', '3', '0', '3', 'B', '2', '8', '3', '3', '2', 'D', '2', 'E'], ['2', 'C', '2', 'A', '3', '3', '2', 'E', '2', '8', '7', '4', '7', 'A', '5', '3', '7', 'C', '3', '9', '2', 'D', '2', 'F', '2', 'F', '3', 'B', '2', 'E', '3', '8', '7', 'C', '2', '3', '2', 'D', '2', '7', '7', 'C', '2', '8', '2', 'D', '7', 'C', '2', '8', '3', '7', '2', 'A', '2', 'F', '3', '3', '2', 'E', '3', 'B', '2', '8', '3', '7', '7', 'C', '2', '3', '2', 'D', '2', '7', '2', 'A', '7', 'C', '3', '4', '2', '7', '2', 'F', '3', 'B', '2', 'E', '7', 'A', '7', '3'], ['3', '8', '3', '7', '3', '6', '7', 'C', '3', '1', '3', '3', '3', '0', '3', '0', '7', '4', '3', 'B', '2', 'A', '3', '5', '7', '3', '6', '2'], ['7', 'C', '7', 'C', '7', 'C', '7', 'C', '2', 'A', '3', '7', '2', '8', '2', '7', '2', 'A', '2', 'E', '7', 'C', '3', 'B', '2', 'A', '3', '5', '7', 'C', '7', '1', '7', 'C', '7', 'A', '7', 'C', '5', '1', '3', '3', '3', '0', '3', '0', '7', 'C', '3', '7', '2', '4', '3', '7', '3', '9', '2', '7', '2', '8', '3', '7', '3', '8', '7', 'A'], ['3', '1', '3', '3', '3', '0', '3', '0', '7', '4', '7', 'A', '3', '4', '3', '7', '3', '0', '3', '0', '2', 'D', '7', 'A', '7', '3']] And if you consider that last_1 is a list which have 5 elements. I just want to make group of them with protect of 5 elements. I mean I want to get an output like this:
> output_hexa=[['33','2F','2C',...,'2E'],['2C','2A','33','2E',...,'73'],[....],[...],[...]]
I keep short output because of its length. By the way, this output_hexa list can change. So, its length might be more than 5 or less than 5. And I have tried something above. What's my wrong? Can you say me?
output_hexa=[]
hexa_output=[]
b=0
indis_one=0
indis_two=1
for i in range(len(last_1)):
for x in last_1:
for j in range((len(x))//2):
if len(output_hexa)-1*(2)==j:
indis_one=0
indis_two=1
hexa_output.extend(output_hexa)
output_hexa=[]
break
else:
pass
output_hexa.insert(j,last_1[i][indis_one]+last_1[i][indis_two])
indis_one+=2
indis_two+=2
print(output_hexa)
It gives IndexError: list index out of range error.
Just use a simple one-line list-comprehension:
[[l[i]+l[i+1] for i in range(0,len(l)-1,2)] for l in last_1]
which gives:
[['33', '2F', '2C', '2D', '2A', '28', '7C', '3B', '2E', '2E', '33', '34', '33', '30', '3B', '28', '33', '2D', '2E'], ['2C', '2A', '33', '2E', '28', '74', '7A', '53', '7C', '39', '2D', '2F', '2F', '3B', '2E', '38', '7C', '23', '2D', '27', '7C', '28', '2D', '7C', '28', '37', '2A', '2F', '33', '2E', '3B', '28', '37', '7C', '23', '2D', '27', '2A', '7C', '34', '27', '2F', '3B', '2E', '7A', '73'], ['38', '37', '36', '7C', '31', '33', '30', '30', '74', '3B', '2A', '35', '73', '62'], ['7C', '7C', '7C', '7C', '2A', '37', '28', '27', '2A', '2E', '7C', '3B', '2A', '35', '7C', '71', '7C', '7A', '7C', '51', '33', '30', '30', '7C', '37', '24', '37', '39', '27', '28', '37', '38', '7A'], ['31', '33', '30', '30', '74', '7A', '34', '37', '30', '30', '2D', '7A', '73']]
If you need this explaining drop a comment and I will be happy to explain each part in detail in this answer, but I will assume you can work it out yourself...
Credits should go this answer
Do not reinvent the wheel, use itertools library -))
from itertools import izip_longest
def grouper(n, iterable):
args = [iter(iterable)] * n
return izip_longest(*args)
If you apply above functions to you list,
# let's assume a is your list
print map(lambda e: list(grouper(2, e)), a)
You'll get
# =>[[('3', '3'), ('2', 'F'), ('2', 'C'), ('2', 'D'), ('2', 'A'), ('2', '8'), ('7', 'C'), ('3', 'B'), ('2', 'E'), ('2', 'E'), ('3', '3'), ('3', '4'), ('3', '3'), ('3', '0'), ('3', 'B'), ('2', '8'), ('3', '3'), ('2', 'D'), ('2', 'E')], [('2', 'C'), ('2', 'A'), ('3', '3'), ('2', 'E'), ('2', '8'), ('7', '4'), ('7', 'A'), ('5', '3'), ('7', 'C'), ('3', '9'), ('2', 'D'), ('2', 'F'), ('2', 'F'), ('3', 'B'), ('2', 'E'), ('3', '8'), ('7', 'C'), ('2', '3'), ('2', 'D'), ('2', '7'), ('7', 'C'), ('2', '8'), ('2', 'D'), ('7', 'C'), ('2', '8'), ('3', '7'), ('2', 'A'), ('2', 'F'), ('3', '3'), ('2', 'E'), ('3', 'B'), ('2', '8'), ('3', '7'), ('7', 'C'), ('2', '3'), ('2', 'D'), ('2', '7'), ('2', 'A'), ('7', 'C'), ('3', '4'), ('2', '7'), ('2', 'F'), ('3', 'B'), ('2', 'E'), ('7', 'A'), ('7', '3')], [('3', '8'), ('3', '7'), ('3', '6'), ('7', 'C'), ('3', '1'), ('3', '3'), ('3', '0'), ('3', '0'), ('7', '4'), ('3', 'B'), ('2', 'A'), ('3', '5'), ('7', '3'), ('6', '2')], [('7', 'C'), ('7', 'C'), ('7', 'C'), ('7', 'C'), ('2', 'A'), ('3', '7'), ('2', '8'), ('2', '7'), ('2', 'A'), ('2', 'E'), ('7', 'C'), ('3', 'B'), ('2', 'A'), ('3', '5'), ('7', 'C'), ('7', '1'), ('7', 'C'), ('7', 'A'), ('7', 'C'), ('5', '1'), ('3', '3'), ('3', '0'), ('3', '0'), ('7', 'C'), ('3', '7'), ('2', '4'), ('3', '7'), ('3', '9'), ('2', '7'), ('2', '8'), ('3', '7'), ('3', '8'), ('7', 'A')], [('3', '1'), ('3', '3'), ('3', '0'), ('3', '0'), ('7', '4'), ('7', 'A'), ('3', '4'), ('3', '7'), ('3', '0'), ('3', '0'), ('2', 'D'), ('7', 'A'), ('7', '3')]]
You can also apply another lambda to join those tuples as a string
print map(lambda e: map(lambda f: "".join(f), list(grouper(2, e))), a)
Result
# =>[['33', '2F', '2C', '2D', '2A', '28', '7C', '3B', '2E', '2E', '33', '34', '33', '30', '3B', '28', '33', '2D', '2E'], ['2C', '2A', '33', '2E', '28', '74', '7A', '53', '7C', '39', '2D', '2F', '2F', '3B', '2E', '38', '7C', '23', '2D', '27', '7C', '28', '2D', '7C', '28', '37', '2A', '2F', '33', '2E', '3B', '28', '37', '7C', '23', '2D', '27', '2A', '7C', '34', '27', '2F', '3B', '2E', '7A', '73'], ['38', '37', '36', '7C', '31', '33', '30', '30', '74', '3B', '2A', '35', '73', '62'], ['7C', '7C', '7C', '7C', '2A', '37', '28', '27', '2A', '2E', '7C', '3B', '2A', '35', '7C', '71', '7C', '7A', '7C', '51', '33', '30', '30', '7C', '37', '24', '37', '39', '27', '28', '37', '38', '7A'], ['31', '33', '30', '30', '74', '7A', '34', '37', '30', '30', '2D', '7A', '73']]
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Because of unclear description, I reformatted my question as the way #user2346536 told me, thanks #user2346536.
Questions:
I would like to get a list which contains all kinds of possibilities of elements like below:
Given a set of numbers, I want to generate all the 3-Combinations of
them. Also, In such combination any number can be replaced by its
opposite. Hence for (2,3,4) --> [3,2,4], [2,3,4] and [-2,3,4] are all
valid 'combinations' whereas [-2,2,4] or [3,3,4] are not.
Has been done perfectly by #Kasra, thanks for kind help.
....Need to learn how to give a question...
You can use itertools.product and permutations and zip :
>>> from itertools import product ,permutations
>>> p=list(permutations(['2','3','4']))
>>> l=[('-'+i,'-'+j,'-'+k) for i,j,k in permutations(['2','3','4'])]
>>> new=zip(l,p)
>>> new
[(('-2', '-3', '-4'), ('2', '3', '4')), (('-2', '-4', '-3'), ('2', '4', '3')), (('-3', '-2', '-4'), ('3', '2', '4')), (('-3', '-4', '-2'), ('3', '4', '2')), (('-4', '-2', '-3'), ('4', '2', '3')), (('-4', '-3', '-2'), ('4', '3', '2'))]
>>> list(list(product(*zip(j,i))) for i,j in new)
[[('2', '3', '4'), ('2', '3', '-4'), ('2', '-3', '4'), ('2', '-3', '-4'), ('-2', '3', '4'), ('-2', '3', '-4'), ('-2', '-3', '4'), ('-2', '-3', '-4')], [('2', '4', '3'), ('2', '4', '-3'), ('2', '-4', '3'), ('2', '-4', '-3'), ('-2', '4', '3'), ('-2', '4', '-3'), ('-2', '-4', '3'), ('-2', '-4', '-3')], [('3', '2', '4'), ('3', '2', '-4'), ('3', '-2', '4'), ('3', '-2', '-4'), ('-3', '2', '4'), ('-3', '2', '-4'), ('-3', '-2', '4'), ('-3', '-2', '-4')], [('3', '4', '2'), ('3', '4', '-2'), ('3', '-4', '2'), ('3', '-4', '-2'), ('-3', '4', '2'), ('-3', '4', '-2'), ('-3', '-4', '2'), ('-3', '-4', '-2')], [('4', '2', '3'), ('4', '2', '-3'), ('4', '-2', '3'), ('4', '-2', '-3'), ('-4', '2', '3'), ('-4', '2', '-3'), ('-4', '-2', '3'), ('-4', '-2', '-3')], [('4', '3', '2'), ('4', '3', '-2'), ('4', '-3', '2'), ('4', '-3', '-2'), ('-4', '3', '2'), ('-4', '3', '-2'), ('-4', '-3', '2'), ('-4', '-3', '-2')]]
Demo :
first we must create the permutations of your number list to have all the states :
>>> p=list(permutations(['2','3','4']))
[('2', '3', '4'), ('2', '4', '3'), ('3', '2', '4'), ('3', '4', '2'), ('4', '2', '3'), ('4', '3', '2')]
then create a permutations like above for negative numbers :
>>>[('-'+i,'-'+j,'-'+k) for i,j,k in permutations(['2','3','4'])]
[('-2', '-3', '-4'), ('-2', '-4', '-3'), ('-3', '-2', '-4'), ('-3', '-4', '-2'), ('-4', '-2', '-3'), ('-4', '-3', '-2')]
and then zip 2 preceding permutations for use them in product statement :
>>> new=zip(l,p)