I want to append a sublist to the previous sublist under certain circumstances, i.e. if its length is less than 2. So, the length of [5] less than 2 and now the previous list is to be extended with the 5 (a+b).
a = [1,1,1,1]
b = [5]
c = [1,1,1]
d = [1,1,1,1,1]
e = [1,2]
f = [1,1,1,1,1,1]
L = [a,b,c,d,e,f]
print 'List:', L
def short(lists):
result = []
for value in lists:
if len(value) <= 2 and result:
result[-1] = result[-1] + value
return result
result = short(L)
print 'Result:', result
The result should be: [[1, 1, 1, 1, 5], [1, 1, 1], [1, 1, 1, 1, 1, 2], [1, 1, 1, 1, 1, 1]]
But from my code, I get: []
This might help
Ex:
a = [1,1,1,1]
b = [5]
c = [1,1,1]
d = [1,1,1,1,1]
e = [1,2]
f = [1,1,1,1,1,1]
L = [a,b,c,d,e,f]
print( 'List:', L)
def short(lists):
result = []
for value in lists:
if len(value) <= 2: #check len
result[-1].extend(value) #extend to previous list
else:
result.append(value) #append list.
return result
result = short(L)
print( 'Result:', result)
Output:
List: [[1, 1, 1, 1], [5], [1, 1, 1], [1, 1, 1, 1, 1], [1, 2], [1, 1, 1, 1, 1, 1]]
Result: [[1, 1, 1, 1, 5], [1, 1, 1], [1, 1, 1, 1, 1, 1, 2], [1, 1, 1, 1, 1, 1]]
Change your function to:
def short(lists):
result = []
for value in lists:
if len(value) < 2 and result:
result[-1].extend(value)
else:
result.append(value)
return result
Related
iterating and appending a list to another list but printing unexpected output: what is wrong?
the last output contains the same elements overwriting the appended elements at
each iteration.
def pascal(n):
"""
print pascal triangle
"""
list = []
if (n > 0):
lst = []
for line in range(1, n + 1):
k = 1
lst.clear()
for i in range(1, line + 1):
lst.append(k)
k = int(k * (line - i)/i)
print(lst)
list.append(lst)
print (list)
else:
print (list)
pascal(5)
**output:**
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[[1, 4, 6, 4, 1], [1, 4, 6, 4, 1], [1, 4, 6, 4, 1], [1, 4, 6, 4, 1], [1, 4, 6, 4, 1]]
**expected output:**
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[[1,], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
def pascal(n):
"""
print pascal triangle
"""
lis = []
if (n > 0):
lst = []
for line in range(1, n + 1):
k = 1
lst.clear()
print(lst,lis) # This is what happening .. your result lis is become empty while you trying to clear lst..! and in the last lst contains value are stored in all the list of lists.
for i in range(1, line + 1):
lst.append(k)
k = int(k * (line - i)/i)
#print(lst)
lis.append(lst)
#print(lis)
else:
print(lis)
pascal(5)
Output:-
[] []
[] [[]]
[] [[], []]
[] [[], [], []]
[] [[], [], [], []]
Reason. In above code list of lists reference the same object. This is because of the fact that lists are referential structures in python. when the last loop iterates lsi store the value in lis in all list of lists..
You can do..
def pascal(n):
"""
print pascal triangle
"""
lis = []
if (n > 0):
for line in range(1, n + 1):
lst = []
k = 1
for i in range(1, line + 1):
lst.append(k)
k = int(k * (line - i)/i)
print(lst)
lis.append(lst)
print(lis)
else:
print(lis)
pascal(5)
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
also not initalise list with a name list as it is a built-in data type..!
Create a new list on each iteration instead of mutating the same one each time.
res = []
if n > 0:
for line in range(1, n + 1):
k = 1
curr = []
for i in range(1, line + 1):
curr.append(k)
k = int(k * (line - i)/i)
print(curr)
res.append(curr)
print(res)
Im trying to get a percentaje from a list of numbers, but it is a little different than the usual methods.
Bassically I need to sum the first index of the list with the last index of the same list. I want the script to do this repeatedly until the lenght of the list equals 2.
Something like this:
list = [1, 1, 2, 1, 1, 1, 1, 1, 1, 1]
list = [2, 2, 3, 2, 2]
list = [4, 4, 3]
list = [7, 4] #here the lenght = 2, so it stops.
final_list = [7, 4]
percentaje = f"%{final_list[0]}{final_list[1]}"
#OUTPUT
#"%74"
Can someone help me to do this? Im not so good with loops :(
This?
L = [1, 1, 2, 1, 1, 1, 1, 1, 1, 1]
while len(L) > 2:
new_L = [L[i]+L[len(L)-1-i] for i in range(len(L)//2)]
if len(L)%2:
new_L.append(L[len(L)//2]) # add middle term alone if any
L = new_L
print(f"%{L[0]}{L[1]}")
list1 = [1, 1, 2, 1, 1, 1, 1, 1, 1, 1]
while len(list1)!=2:
for i in range (0, int(len(list1)/2)):
list1[i] = list1[i] + list1[len(list1)-1]
list1 = list1[:-1]
print(list1)
output:
[7, 4]
How can I turn a list such as:
data_list = [1,2,3,1,2,3,1,2,3,3,1,2,3,3]
into a list of lists such as:
new_list = [ [1,2,3], [1,2,3], [1,2,3,3], [1,2,3,3] ]
Using a loop:
data = [1,2,3,1,2,3,1,2,3,3,1,2,3,3]
result =[]
for n in data:
if n == 1 or result == []:
result.append([])
result[-1].append(n)
[[1, 2, 3], [1, 2, 3], [1, 2, 3, 3], [1, 2, 3, 3]]
How about a generator like this?
def grouped(it, boundary):
group = []
for val in it:
if val == boundary and group:
yield group
group = []
group.append(val)
if group:
yield group
for grp in grouped([1,2,3,1,2,3,1,2,3,3,1,2,3,3], 1):
print(grp)
Output:
[1, 2, 3]
[1, 2, 3]
[1, 2, 3, 3]
[1, 2, 3, 3]
x = [2, 1, 2, 0, 1, 2, 2]
I want to splice the above list into sublists of length = [1, 2, 3, 1]. In other words, I want my output to look something like this:
[[2], [1, 2], [0, 1, 2], [2]]
where my first sublist is of length 1, the second sublist is of length 2, and so forth.
You can use itertools.islice here to consume N many elements of the source list each iteration, eg:
from itertools import islice
x = [2, 1, 2, 0, 1, 2, 2]
length = [1, 2, 3, 1]
# get an iterable to consume x
it = iter(x)
new_list = [list(islice(it, n)) for n in length]
Gives you:
[[2], [1, 2], [0, 1, 2], [2]]
Basically we want to extract certain lengths of substrings.
For that we need a start_index and an end_index. The end_index is your start_index + the current length which we want to extract:
x = [2, 1, 2, 0, 1, 2, 2]
lengths = [1,2,3,1]
res = []
start_index = 0
for length in lengths:
res.append(x[start_index:start_index+length])
start_index += length
print(res) # [[2], [1, 2], [0, 1, 2], [2]]
Added this solution to the other answer as it does not need any imported modules.
You can use the following listcomp:
from itertools import accumulate
x = [2, 1, 2, 0, 1, 2, 2]
length = [1, 2, 3, 1]
[x[i - j: i] for i, j in zip(accumulate(length), length)]
# [[2], [1, 2], [0, 1, 2], [2]]
I have recently been playing around with some code recently which involved an iterator:
"""IntegerPartitions.py
Generate and manipulate partitions of integers into sums of integers.
D. Eppstein, August 2005.
https://www.ics.uci.edu/~eppstein/PADS/IntegerPartitions.py
"""
def mckay(n):
"""
Integer partitions of n, in reverse lexicographic order.
The output and asymptotic runtime are the same as mckay(n),
but the algorithm is different: it involves no division,
and is simpler than mckay, but uses O(n) extra space for
a recursive call stack.
"""
if n == 0:
yield []
if n <= 0:
return
for p in mckay(n-1):
if len(p) == 1 or (len(p) > 1 and p[-1] < p[-2]):
p[-1] += 1
yield p
p[-1] -= 1
p.append(1)
yield p
p.pop()
The program takes in an integer, and returns a generator which outputs the partitions of that integer.
I have noticed something weird, however, when I try to use it in code.
>>> p = mckay(4)
>>> print list(p)
[[], [], [], [], []]
>>> q = mckay(4)
>>> cumulator = []
>>> for x in q :
... cumulator.append(x)
>>> print cumulator
[[], [], [], [], []]
>>> print list(mckay(4))
[[], [], [], [], []]
>>> r = mckay(4)
>>> for x in r :
... print x
[4]
[3, 1]
[2, 2]
[2, 1, 1]
[1, 1, 1, 1]
>>> for x in mckay(4) :
... print x
[4]
[3, 1]
[2, 2]
[2, 1, 1]
[1, 1, 1, 1]
The partitions don't seem to show up unless I print them one by one. Is this a bug in the language (my version is Python 2.7.6 on Ubuntu Trusty), or is there something I am missing? I have looked around on Google, and cannot seem to find anything pertaining to this.
I thought it may have something to do with the recursive call, but I tried it with the following code, and found similar results
def mckay(n):
"""
Integer partitions of n, in reverse lexicographic order.
Note that the generated output consists of the same list object,
repeated the correct number of times; the caller must leave this
list unchanged, and must make a copy of any partition that is
intended to last longer than the next call into the generator.
The algorithm follows Knuth v4 fasc3 p38 in rough outline.
"""
if n == 0:
yield []
if n <= 0:
return
partition = [n]
last_nonunit = (n > 1) - 1
while True:
yield partition
if last_nonunit < 0:
return
if partition[last_nonunit] == 2:
partition[last_nonunit] = 1
partition.append(1)
last_nonunit -= 1
continue
replacement = partition[last_nonunit] - 1
total_replaced = replacement + len(partition) - last_nonunit
reps,rest = divmod(total_replaced,replacement)
partition[last_nonunit:] = reps*[replacement]
if rest:
partition.append(rest)
last_nonunit = len(partition) - (partition[-1]==1) - 1
The results are almost identical:
>>> p = mckay(4)
>>> print list(p)
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
>>> q = mckay(4)
>>> cumulator = []
>>> for x in q :
... cumulator.append(x)
>>> print cumulator
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
>>> print list(mckay(4))
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
>>> r = mckay(4)
>>> for x in r :
... print x
[4]
[3, 1]
[2, 2]
[2, 1, 1]
[1, 1, 1, 1]
>>> for x in mckay(4) :
... print x
[4]
[3, 1]
[2, 2]
[2, 1, 1]
[1, 1, 1, 1]
The problem is that the function mckay is modifying the same list object, so when you call list() on it you actually get a list containing 4 items that actually point to the same object. So, as in the end the list object is empty all you get is list with empty lists.
>>> p = mckay(4)
>>> [id(x) for x in p]
[139854369904832, 139854369904832, 139854369904832, 139854369904832, 139854369904832]
>>> for x in mckay(4):
print x, '-->', id(x)
[4] --> 140446845125552
[3, 1] --> 140446845125552
[2, 2] --> 140446845125552
[2, 1, 1] --> 140446845125552
[1, 1, 1, 1] --> 140446845125552
>>> x # The actual list object is empty at the end of the iteration
[]
>>> id(x)
140446845125552
But when you loop over it you're simply printing the returned object immediately hence the different output, a fix here is to yield a shallow copy:
yield p[:]