I am struggling to combine specific list elements from a tuple. Would love any feedback or help! I am new to Python, so apologies if this is not a good question.
If I have a tuple list like this:
tuple_1 = [('A', 'B', 'C', 'D'), ('A', 'H'), ('B', 'C', 'D', 'A')]
I want to combine elements 'B', 'C', and 'D' from every tuple in the list:
tuple_1_new = [('A', 'BCD'), ('A', 'H'), ('BCD', 'A')]
My code looks like this:
next_insert = [(iter(x)) for x in tuple_1]
tuple_1_new = [i next(next_insert) next(next_insert) if i == "B" else i for i in next_insert]
but when I print(tuple_1_new), it is giving me an output of:
[<tuple_iterator object at ...>, <tuple_iterator object at ...>, <tuple_iterator object at ...>]
I feel like my code is correct, but I'm confused with this output. Again, sorry if this is a dumb question. Would appreciate any help - thanks!
CodePudding user response:
def foo(arr):
w = "".join(arr)
ind = w.find("BCD")
if ind >= 0:
ans = list(arr)
return tuple(ans[:ind] ["BCD"] ans[ind 3:])
return arr
[foo(x) for x in tuple_1]
# [('A', 'BCD'), ('A', 'H'), ('BCD', 'A')]
CodePudding user response:
Another solution, using generator:
tuple_1 = [("A", "B", "C", "D"), ("A", "H"), ("B", "C", "D", "A")]
def fn(x):
while x:
if x[:3] == ("B", "C", "D"):
yield "".join(x[:3])
x = x[3:]
else:
yield x[0]
x = x[1:]
out = [tuple(fn(t)) for t in tuple_1]
print(out)
Prints:
[('A', 'BCD'), ('A', 'H'), ('BCD', 'A')]
CodePudding user response:
A list comprehension answer:
[tuple([t for t in tup if t not in ['B', 'C', 'D']] [''.join([t for t in tup if t in ['B', 'C', 'D']])]) for tup in tuple_1]
Although not quite getting the desired output, prints:
[('A', 'BCD'), ('A', 'H', ''), ('A', 'BCD')]
Note: In a 'simple' list comprehension, the 'for x in iterable_name' creates a processing loop using 'x' (or a collection of names if expanding a tuple or performing a zip extraction) as variable(s) in each loop. When performing list comprehension within a list comprehension (for loop inside for loop), each loop will contribute one or more variables, which obviously must not incur a name collision.
CodePudding user response:
Assuming the strings are single letters like in your example:
tuple_1_new = [tuple(' '.join(t).replace('B C D', 'BCD').split())
for t in tuple_1]
Or with Regen:
tuple_1_new = [tuple(re.findall('BCD|.', ''.join(t)))
for t in tuple_1]