Reputation: 11
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
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
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
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
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