elements to python list - python

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)

Related

Array gets swapped before swap function is used [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 2 years ago.
I am trying to write a simple swap function, where the elements of an array get swapped once. The idea is I want to swap it once and check if it is the same as the unswapped array (which it will be for some cases, when all the elements are same, or something like that)
def swap(arr, pos):
if pos <= len(arr) - 1 and num != 0:
arr[pos], arr[pos + 1] = arr[pos + 1], arr[pos]
else:
pass
return arr
some = [1,2,3,4]
#print(some)
for i in range(len(some) - 1):
arr0 = some
arr1 = swap(some, i)
print(arr0, arr1)
And the output for this is:
[2, 1, 3, 4] [2, 1, 3, 4]
[2, 3, 1, 4] [2, 3, 1, 4]
[2, 3, 4, 1] [2, 3, 4, 1]
And I'm expecting something like:
[1, 2, 3, 4] [2, 1, 3, 4]
...
Why does the arr0 array get swapped?
arr0 = some[:]
this should help you, it will copy the instance of the array not the location of it because when you make change to your some this will effect every array that is a directional copy of it
use copy() method.
arr0 = some.copy()
Code:
def swap(arr, pos):
if pos <= len(arr) - 1 and num != 0:
arr[pos], arr[pos + 1] = arr[pos + 1], arr[pos]
else:
pass
return arr
some = [1,2,3,4]
#print(some)
for i in range(len(some) - 1):
arr0 = some.copy()
arr1 = swap(some, i)
print(arr0, arr1)
Output:
[1, 2, 3, 4] [2, 1, 3, 4]
[2, 1, 3, 4] [2, 3, 1, 4]
[2, 3, 1, 4] [2, 3, 4, 1]
Other answers have made it clear. I just want to say, why not write
def swap(arr, pos):
if pos <= len(arr) - 1 andpos < 0:
arr[pos], arr[pos + 1] = arr[pos + 1], arr[pos]
else:
pass
return arr
some = [1,2,3,4]
#print(some)
for i in range(len(some) - 1):
print("before swap: ", some)
swap(some, i)
print("after swap: ", some)
Then you do not need to copy the list. Just print swap log in two lines.

How to split a nested list of ints into a a list

lst = [[1, 5],
[2, 2]
this is my nested list, I need to make a list of the points of this:
output = [[1, 5, 2, 2]
here is my attempt at this which works for this case but fails if I have an example where the row length is 6 or greater than 4
new_lst = []
for x in range(len(lst)):
for y in range(0, len(lst[x]), 2):
new_lst.append([lst[x][y],lst[x][y+1]])
counter_a = 0
counter_b = 1
output = []
while counter_b - 4 <= len(lst):
output.append(new_lst[counter_a] + new_lst[counter_a + 2])
output.append(new_lst[counter_b] + new_lst[counter_b + 2])
counter_a += 4
counter_b += 4
print(output)
How about this? This is general for all lists with size nxm where n and m are even numbers. The logic is to iterate with a step of 2 in both row and column, then take the block of 2x2 elements and append it to the output list.
lst = [[1, 6, 5, 6],
[2, 5, 6, 8],
[7, 2, 8, 1],
[4, 4, 7, 3]]
output = []
for j in range(0, len(lst), 2):
for i in range(0, len(lst[0]), 2):
output.append([lst[j][i], lst[j][i+1], lst[j+1][i], lst[j+1][i+1]])
output : [[1, 6, 2, 5], [5, 6, 6, 8], [7, 2, 4, 4], [8, 1, 7, 3]]
Try using:
print([x for i in list(zip(*[[i[:2], i[2:]] for i in lst])) for x in [i[0] + i[1], i[2] + i[3]]])

How to add a sublist to a sublist?

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

how to create a list of values based on a index python

I have a list
input :
value = [1,2,2,1,1,3,1,3,4,4,5,5,4,6,6]
expected output:
[[1,2,3,1,1,3,1],[3],[4,4,5,5,4],[6,6]]
Explanation:
1) once i iterate over value list first element would we 1 index's of one are
[0 3 4 6] . i want to store start and end number of a index eg (value[ 0 : 6 ]) to a new list and remove from Existing one list looks like value= [3,4,4,5,5,4,6,6]
2) once i iterate on value next input would be 3 index of value 3 is [0] store it in a list and as follows
I have tried few lines of code
1) i have iterated a list with index and value with numpy i have found the index stored in a table
import numpy as np
final_list=[]
top_list=[1,2,2,1,1,3,1,3,4,4,5,5,4,6,6]
matched_input=[]
for i,j in enumerate(top_list):
if(len(matched_input)==0):
values = np.array(top_list)
matched_input= np.where(j == values)[0]
matched_input=np.array(matched_input).tolist()
final_list.append(top_list[matched_input[0]:matched_input[-1]+1])
#print matched_input
elif(len(matched_input)>0 and i not in range(matched_input[-1]+1)):
values= np.array(top_list[matched_input[-1]+1:])
matched_input_updated= np.where(j == values)[0]
matched_input_updated=np.array(matched_input_updated).tolist()
final_list.append(top_list[matched_input_updated[0]:matched_input_updated[-1]+1])
try this:
input = [1, 2, 2, 1, 1, 3, 1, 3, 4, 4, 5, 5, 4, 6, 6]
result = []
while len(input) > 0: # can be just while input
first_element = input[0]
last_index_of_first_element = len(input) - (input[::-1].index(first_element) + 1)
result.append(input[:last_index_of_first_element + 1])
input = input[last_index_of_first_element + 1:]
print(result)
Output:
[[1, 2, 2, 1, 1, 3, 1], [3], [4, 4, 5, 5, 4], [6, 6]]
basically, as long as there is input, I take the first element, then find it's last index (by reversing the list, finding the first index, and subtracting from the len), and then use slicing to extract the correct sublist and append to result.
Slight variation on the other answer, without modifying the input list:
value = [1, 2, 2, 1, 1, 3, 1, 3, 4, 4, 5, 5, 4, 6, 6]
next_idx = 0
value_rev = value[::-1]
result = []
while next_idx < len(value):
prev_idx = next_idx
next_idx = len(value) - value_rev.index(value[prev_idx])
result.append(value[prev_idx:next_idx])
print(result)
# [[1, 2, 2, 1, 1, 3, 1], [3], [4, 4, 5, 5, 4], [6, 6]]
from collections import defaultdict
value = [1,2,2,1,1,3,1,3,4,4,5,5,4,6,6]
d = defaultdict(list)
[d[v].append(i) for i, v in enumerate(value)]
i, out = 0, []
while i < len(value):
i2 = d[value[i]][-1]
out.append(value[i:i2+1])
i = i2 + 1
print(out)
Prints:
[[1, 2, 2, 1, 1, 3, 1], [3], [4, 4, 5, 5, 4], [6, 6]]

Find K subsets of a list with elements 1...N while preserving the order of the elements

Given a list of integers from 1...N I am trying to find K subsets of the elements, while preserving the order of the elements. For example, when N = 4 and K = 2:
[1] [2, 3, 4]
[1, 2] [3, 4]
[1, 2, 3] [4]
[1, 2, 3, 4] []
Would be the correct output.
So far I've gotten the first column of possibilities. But I am struggling to get the correct logic.
final = [['' for x in range(K)] for y in range(N)]
i = 0
for k in range(0, K):
# row tracker
i = 0
while i < N:
if k > 0:
st = len(final[i][k - 1])
else:
st = 0
for j in range(0, N):
tmp = ""
prefix = chemicals[:j + 1]
tmp = tmp.join(str(i) for i in prefix)
final[i][k] = tmp
i += 1
print
Again, correct output would be:
[1] [2, 3, 4]
[1, 2] [3, 4]
[1, 2, 3] [4]
[1, 2, 3, 4] []
Where a set can be empty.
Update: This is the correct output for N=4, K=3
[1] [2] [3, 4]
[1] [2, 3] [4]
[1] [2, 3, 4] []
[1, 2] [3] [4]
[1, 2] [3, 4] []
[1, 2, 3] [4] []
[1, 2, 3, 4] [] []
You can use a function that iterates an index from a given starting number, defaulting to 1, to n, yields a range of numbers from the starting number to the index, and recursively joins the subsets from the recursive call with a starting index of one higher and one less subset, until either starting index is greater than n or k becomes 1, at which point the remaining range should be yielded:
def get_subsets(n, k, s=1):
if s > n or k == 1:
yield [list(range(s, n + 1))] + [[] for _ in range(1, k)]
return
for i in range(s, n + 1):
for subsets in get_subsets(n, k - 1, i + 1):
yield [list(range(s, i + 1))] + subsets
so that:
for s in get_subsets(4, 2):
print(*s)
outputs:
[1] [2, 3, 4]
[1, 2] [3, 4]
[1, 2, 3] [4]
[1, 2, 3, 4] []
and that:
for s in get_subsets(4, 3):
print(*s)
outputs:
[1] [2] [3, 4]
[1] [2, 3] [4]
[1] [2, 3, 4] []
[1, 2] [3] [4]
[1, 2] [3, 4] []
[1, 2, 3] [4] []
[1, 2, 3, 4] [] []
I think a simple list comprehension with slicing should suffice. You may want to use itertools.combinations as well:
import itertools
N = 4
K = 2
elements = list(range(1, N + 1))
final = [[elements[a:b] for a, b in zip([0] + cuts, cuts + [N])]
for cuts in (list(c) for c in itertools.combinations(elements, K - 1))]
for x in final:
print(*x)
Output:
[1] [2, 3, 4]
[1, 2] [3, 4]
[1, 2, 3] [4]
[1, 2, 3, 4] []

Categories