-1

I have a sample list of data like this:

list_ = [
    (['0.640', '0.630', '0.64'], ['0.61', '0.65', '0.53']), 
    (['20.00', '21.00', '21.00'], ['21.00', '22.00', '22.00']), 
    (['0.025', '0.025', '0.026'], ['0.150', '0.150', '0.130'])
] 

I'm trying to merge all lists in tuple into tuple, which would be the result of list of tuples.

Now I would like to get a merged list as follows

output = [
    ('0.640', '0.630', '0.64', '0.61', '0.65', '0.53'), 
    ('20.00', '21.00', '21.00', '21.00', '22.00', '22.00'), 
    ('0.025', '0.025', '0.026', '0.150', '0.150', '0.130')
]
# or 
output = [
    ['0.640', '0.630', '0.64', '0.61', '0.65', '0.53'], 
    ['20.00', '21.00', '21.00', '21.00', '22.00', '22.00'], 
    ['0.025', '0.025', '0.026', '0.150', '0.150', '0.130']
]

Any help appreciated. Thanks in advance!

flakes
  • 21,558
  • 8
  • 41
  • 88
Jiro Akira
  • 91
  • 5
  • 1
    @HarshalParekh Most likely due to being a common question with many similar posts existing. – flakes Sep 05 '20 at 19:46
  • have you considered using .replace() to replace the square brackets with empty spaces? somewhat primitive, but effective.. – Rachel Gallen Sep 05 '20 at 20:11

3 Answers3

2
from itertools import chain
output = [tuple(chain.from_iterable(t)) for t in list_]

Use chain from itertools.

Harshal Parekh
  • 5,918
  • 4
  • 21
  • 43
  • 1
    Not saying that isn't the case, but that seems highly speculative. Do you have any proof on that? I wouldn't immediately blame the other posters- that sounds unfair. – flakes Sep 05 '20 at 19:12
  • This solution takes 1.29 µs ± 39.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) while my solution takes 818 ns ± 36.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each). This is solution is 57% slower than mine. Why has this answer been accepted? – Gil Pinsky Sep 05 '20 at 19:25
  • @flakes I did notice a change in rep, that answerer has removed the post and deleted the downvote. – Harshal Parekh Sep 05 '20 at 19:34
  • @GilPinsky using sum() to flatten list is the worst possible solution when it comes to 1000s of values in the lists/tuples. read more here: https://stackoverflow.com/a/952946/8430155 – Harshal Parekh Sep 05 '20 at 19:35
  • 1
    @GilPinsky High speed solutions are nice, but when working with Python I will always favor readability and flexibility over that. `from_iterable` is the common approach for this problem, and is optimized for multiple inputs by using a generator to return the value. In this case we only need to ever construct one container, whereas `sum` will create `N - 1` containers as it iteratively constructs the result. – flakes Sep 05 '20 at 19:42
  • @flakes In python, summing two lists concatenates them. So I find that using sum on a list of lists is the most intuitive approach to concatenating all elements of said list. Regarding the efficiency, I have checked with huge lists as well and my code just becomes more efficient as the size increases. Please explain your claim. I saw the link Harshal has posted but in an empirical test this doesn't seem to be true. – Gil Pinsky Sep 05 '20 at 19:50
  • @GilPinsky the original author of the post has put up a note that sum() is inefficient, what more proof do you need? There is also a comment which explains the algorithm used by sum(). Also, I agree with flakes. – Harshal Parekh Sep 05 '20 at 19:53
  • @GilPinsky Think more than two lists. consider `list_=[[(a, b, c, d, e)]]` where each of `a, b, c, d, e` are lists/tuples with many values. The memory complexity of the operation increases greatly with intermittent results `a + b`, `a + b + c`, etc, along with time complexity to construct new lists on each iteration. – flakes Sep 05 '20 at 19:53
  • 1
    @GilPinsky if you want further proof look at the official documentation of [`sum`](https://docs.python.org/3/library/functions.html#sum) "For some use cases, there are good alternatives to `sum()`. The preferred, fast way to concatenate a sequence of strings is by calling `''.join(sequence)`. To add floating point values with extended precision, see `math.fsum()`. **To concatenate a series of iterables, consider using `itertools.chain()`**." – flakes Sep 05 '20 at 19:59
  • Yes indeed it is more efficient, but it depends on the number of lists so if you don't have a high enough number of lists (which is in the thousands), you may severely underperform if you use itertools.chain! Asymptotically itertools.chain is superior. I think the reason they say **consider** is because of this reason. – Gil Pinsky Sep 05 '20 at 20:02
1
  • list comprehension
[[item for internal_list_ in tuple_ for item in internal_list_] for tuple_ in list_]
  • numpy
np.array(list_).reshape((len(list_), -1))
0
output = [x[0]+x[1] for x in list_]

If you want a general solution you don't have to import itertools in this case as others have suggested. This works for n-tuples:

output = [sum([*x], []) for x in list_]

This solution will be superior when you don't have thousands of lists, but inferior otherwise.

Gil Pinsky
  • 2,388
  • 1
  • 12
  • 17
  • 2
    What if there are more than 2 lists in the tuple? – Harshal Parekh Sep 05 '20 at 19:05
  • Never use sum() to flatten a list. Read comments here: https://stackoverflow.com/a/952946/8430155 – Harshal Parekh Sep 05 '20 at 19:36
  • 1
    I've already tried your second method, it works effective for me for n-lists , thank you for your effective way – Jiro Akira Sep 05 '20 at 19:39
  • @JiroAkira read here https://stackoverflow.com/a/952946/8430155 why sum() should never be used – Harshal Parekh Sep 05 '20 at 19:39
  • @HarshalParekh I would refrain from saying **never** since for a small number of lists (ie, not in the thousands) you will be better off using sum() if time matters – Gil Pinsky Sep 05 '20 at 20:05
  • @GilPinsky it’s also unnecessary ugly and confusing to read. Please read the linked post. – Harshal Parekh Sep 05 '20 at 20:07
  • @HarshalParekh I have read. As I have said before - In python, summing two lists concatenates them. So I find that using sum on a list of lists is the most intuitive approach to concatenating all elements of said list. Having said that, many times I prefer the more efficient way so I would choose my solution when the number of lists is not big enough and yours otherwise. – Gil Pinsky Sep 05 '20 at 20:17
  • @GilPinsky you find that, doesn’t mean it’s the right way. On the linked post, hundreds of users have said that it’s unnecessary ugly and confusing to read. – Harshal Parekh Sep 05 '20 at 20:19
  • @HarshalParekh The author himself said it's fun... top commenters have said: "it's neat and clever", "The append operation on lists forms a Monoid, which is one of the most convenient abstractions for thinking of a + operation in a general sense (not limited to numbers only). " To me this seems one of the purest ways to implement this. I only agree that the performance is concerning when dealing with a large number of lists. Otherwise, I prefer this way. – Gil Pinsky Sep 05 '20 at 20:37