13

Say I have the following lists:

a = 1
b = [2,3]
c = [4,5,6]

I want to concatenate them such that I get the following:

[1,2,3,4,5,6]

I tried the usual + operator:

>>> a+b+c
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'list'

This is because of the a term. It is just an integer. So I convert everything to a list:

>>> [a]+[b]+[c]
[1, [2, 3], [4, 5, 6]]

Not quite what I'm looking for.

I also tried all the options in this answer, but I get the same int error mentioned above.

>>> l = [a]+[b]+[c]
>>> flat_list = [item for sublist in l for item in sublist]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
TypeError: 'int' object is not iterable

It should be simple enough, but nothing works with that term a. Is there any way to do this efficiently? It doens't necessarily have to be pythonic.

Ajay H
  • 794
  • 2
  • 11
  • 28
  • 1
    Question: why do you have inconsistent data types in the first place? Why not use lists consistently for all the variables? – Barmar Oct 01 '17 at 21:44
  • My problem wasn't this simple. It was a part of a function where I updated the values of a list constantly (list of lists with variable lengths). It would be messy had I written it all here. But this was by basic error. – Ajay H Oct 01 '17 at 21:49

3 Answers3

13

There's nothing that will automatically treat an int as if it's a list of one int. You need to check whether the value is a list or not:

(a if type(a) is list else [a]) + (b if type(b) is list else [b]) + (c if type(c) is list else [c])

If you have to do this often you might want to write a function:

def as_list(x):
    if type(x) is list:
        return x
    else:
        return [x]

Then you can write:

as_list(a) + as_list(b) + as_list(c)
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I was actually running `a+b+c` for lists that change sizes. I only considered `a`. But at some point, even c became 1 integer. Got that from your function. Thanks – Ajay H Oct 01 '17 at 21:42
  • Are you going to fix the question to have the correct value of `a`? – Barmar Oct 01 '17 at 21:43
2

You can use itertools:

from itertools import chain

a = 1
b = [2,3]
c = [4,5,6]
final_list = list(chain.from_iterable([[a], b, c]))

Output:

[1, 2, 3, 4, 5, 6]

However, if you do not know the contents of a, b, and c ahead of time, you can try this:

new_list = [[i] if not isinstance(i, list) else i for i in [a, b, c]]
final_list = list(chain.from_iterable(new_list))
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
1

Accepted answer is the best way. Adding another variation. Explanation in comments as well.

from collections.abc import Iterable


a = "fun" 
b = [2,3]
c = [4,5,6]


def flatten(lst):
    for item in lst:
        if isinstance(item,Iterable) and not isinstance(item,str): # checking if Iterable and taking care of strings as well
            yield from flatten(item)
        else:
            yield item

# test case:

res = []
res.extend([a]+[b]+[c]) # casting them into lists,  [a]+[b]+[c] [1, [2, 3], [4, 5, 6]]
print(list(flatten(res)))

Produces

['fun', 2, 3, 4, 5, 6]

[Program finished] 
Subham
  • 397
  • 1
  • 6
  • 14