Julien Joos
Julien Joos

Reputation: 11

TypeError: can't multiply sequence by non-int of type 'list'

I'm trying to solve an excercice and I've got to convert this

L = ([[4,1],[2,2],[2,"test"],[3,3],[1,"bonjour"]])
decompress (L)

into this

[1,1,1,1,2,2,"test","test",3,3,3,"bonjour"]

and this is how I started :

def por(L):
    result = []
    n = len(L)
    for i in range(n):
        m = len(L[i])
        for j in range(m):
            mult = L[j]*L[j-1]
            result.append(mult)
    return result

por([[4,1],[2,2],[2,"test"],[3,3],[1,"bonjour"]])

Traceback (most recent call last):
File "<pyshell#50>", line 1, in <module>
por([[4,1],[2,2],[2,"test"],[3,3],[1,"bonjour"]])
File "<pyshell#49>", line 7, in por
mult = L[j]*L[j-1]
TypeError: can't multiply sequence by non-int of type 'list'

I don't get what is wrong, could someone help me, it's for my exams !!!!

Upvotes: 0

Views: 1881

Answers (4)

Bill Lynch
Bill Lynch

Reputation: 81986

I personally find itertools makes our life easier with these problems:

def por(L):
    chains = (itertools.repeat(b, a) for a, b in L)
    return list(itertools.chain_from_iterable(chains))

or, one one line:

>>> list(itertools.chain_from_iterable(itertools.repeat(b, a) for a, b in L))
[1, 1, 1, 1, 2, 2, 'test', 'test', 3, 3, 3, 'bonjour']

Upvotes: 0

Padraic Cunningham
Padraic Cunningham

Reputation: 180481

def por(L):
    # add each sublist element 1  sublist element 0 times
    return [sub_list[1]  for sub in L for _ in xrange(sub_list[0])]

Or:

def por(L):
    return [ele  for times, ele in L for _ in xrange(times)]

Using something similar to your own code:

def por(L):
    result = []
    # loop over each sublist
    for sub_list in L:
        # get first sublist element and loop in that range
        times = sub_list[0] # actually accessing the first element of each sublist
        for _ in xrange(times): # use range for python 3
            # here we are adding each sublist element 1 element 0 times
            result.append(sub_list[1])
    return result

In your in code you are trying to multiply L[j]* L[j-1] which are the both lists as you can see when you add a print L[j],L[j-1] in your code:

[4, 1] [1, 'bonjour']
[2, 2] [4, 1]
[4, 1] [1, 'bonjour']
[2, 2] [4, 1]
[4, 1] [1, 'bonjour']
[2, 2] [4, 1]
[4, 1] [1, 'bonjour']
[2, 2] [4, 1]
[4, 1] [1, 'bonjour']
[2, 2] [4, 1]

Upvotes: 1

jamylak
jamylak

Reputation: 133634

>>> L = ([[4,1],[2,2],[2,"test"],[3,3],[1,"bonjour"]])
>>> [y for x, y in  L for i in range(x)]
[1, 1, 1, 1, 2, 2, 'test', 'test', 3, 3, 3, 'bonjour']

Upvotes: 0

Alex Martelli
Alex Martelli

Reputation: 882123

Perhaps simplest:

result = []
for repetitions, contents in L:
    for _ in range(repetitions):
        result.append(contents)

Yes, there are better ways, some of which have already been posted, but maybe the simplicity of this one will help.

Avoiding the len calls and the indexing, in favor of just looping over the list and unpacking each of its items into repetitions and content, I feel contributes to the simplicity; so does building the result up from an empty list with repeated append calls, rather than the more idiomatic but perhaps murkier-to-a-beginner use of list comprehensions &c.

Upvotes: 1

Related Questions