Adding new rows to an array dynamcally - python

I want to initialize an empty list and keep on adding new rows to it. For example.
myarray=[]
now at each iteration I want to add new row which I compute during iteration. For example
for i in range(5):
calc=[i,i+1,i+4,i+5]
After calc I want to add this row to myarray. Therfore after 1st iteration myarray would be 1X4, after 2nd iteration it would be 2X4 etc. I tried numpy.concatenate. It simply adds to same row ie I get 1X4 then 1X8. I tried vstack as well but since myarray is initially [] it gives error "all the input array dimensions except for the concatenation axis must match exactly"

It looks like you need a multi dimensional array
calc = [[0, 1, 4, 5]]
for i in range(1, 5):
calc.append([i, i+1, i+4, i+5])
Will yield you the following array
calc = [[0, 1, 4, 5], [1, 2, 5, 6], [2, 3, 6, 7], [3, 4, 7, 8], [4, 5, 8, 9]]
To access the various elements of calc you can address it like the following
calc[0] returns [0,1,5,6]
calc[1] returns [1,2,5,6]

I'm pretty sure this works, unless I'm misunderstanding:
mylist = [] #I'm using a list, not an array
for i in range(5):
calc=[i,i+1,i+4,i+5]
mylist.append(calc) #You're appending a list into another list, making a nested list
Now, a little more general knowledge. Append vs. Concatenate.
You want to append if you want to add into a list. In this case, you're adding a list into another list. You want to concatenate if you want to 'merge' two lists together to make a single list - which is why your implementation was not making a nested list.

Related

Getting the value of List and sum in python

I newbie in python and I have a trouble how can I make my loop with that shape below and getting the total number of each line, I tried the code below but it seems it doesn't right
I should use list in loop like the declaration below, I appreciate who can help me.
data = [1, 2, 3, 4, 5]
Expected output:
[1, 2, 3, 4, 5, 15]
[2, 3, 4, 5, 14]
[3, 4, 5, 12]
[4, 5, 9]
[5, 5]
This is what I tried but it doesn't use list ,I think it's wrong
data = 5
for i in range(data):
for j in range(i+1):
print("[",j+1, end=" "+" ]")
print("[ ]")
Usually in these kind of exercises you shouldn't build the string yourself(talking about brackets). Those brackets are part of the representation of the lists in Python. So build your list object and the final result is gonna be printed as you expected. So don't attempt to put individual numbers, spaces, brackets together yourself.
You can use:
data = [1, 2, 3, 4, 5]
for i in range(len(data)):
slice_ = data[i:]
print(slice_ + [sum(slice_)])
Explanation:
Basically in every iteration, you create a slice of the list by specifying the start point to the end. Start point comes from the range(len(data)) range object.
first iteration : From index 0 to end.
second iteration: From index 1 to end.
...
Then you concatenate the slice with the sum of the slice. But you have to put the sum inside a list because a list can't be concatenated with an int. Of course other option is to .append() it before printing:
for i in range(len(data)):
slice_ = data[i:]
slice_.append(sum(slice_))
print(slice_)

Assign inner list to new variable - Python

I stumble upon some issue with list. I have nested list like this one
[[1, 2, 3], [4, 5, 6],[7, 8, 9]]
This list can be arbitrarily large and inner list does not need to be in the same length(size).
What I would like to achieve is to take out each inner list and assign to new variable.
This means in our toy example the following.
Var1=[1,2,3]
Var2=[4,5,6]
Var3=[7,8,9]
I can index it manually in toy example each inner list, but this not desired result. I need to store as separate variable each inner list. Moreover I prefer function to do this for me.
What I need is a function that takes nested list and assigns each inner list to variable automatically. Input of function should be nested list and output should be each inner list assign to variable. The solution should scale to larger list size.
This should work:
main_list = [[1, 2, 3], [4, 5, 6],[7, 8, 9]]
for i in range(len(main_list)):
declare_statement = f'Var{i} = {main_list[i]}'
exec(declare_statement)
'''
now each value of the main_list is stored in variable different variable with
prefix "Var" and index of that value as postfix
'''
That means print(Var0) would display [1, 2, 3], print(Var1) would display [4, 5, 6] and so on but honestly I don't see a point to this.
You could've achieved the same thing by print(main_list[0]) and print(main_list[1]) it is just a waste of memory to assign each value of a list to a variable and it also defeats the purpose of lists and arrays.

Python: Inplace Merge sort implementation issue

I am implementing inplace merge sort algorithm in python3. Code takes an input array and calls it self recursively (with split array as input) if length of the input array is more than one. After that, it joins two sorted arrays. Here is the code
def merge_sort(array):
"""
Input : list of values
Note :
It divides input array in two halves, calls itself for the two halves and then merges the two sorted halves.
Returns : sorted list of values
"""
def join_sorted_arrays(array1, array2):
"""
Input : 2 sorted arrays.
Returns : New sorted array
"""
new_array = [] # this array will contain values from both input arrays.
j = 0 # Index to keep track where we have reached in second array
n2 = len(array2)
for i, element in enumerate(array1):
# We will compare current element in array1 to current element in array2, if element in array2 is smaller, append it
# to new array and look at next element in array2. Keep doing this until either array2 is exhausted or an element of
# array2 greater than current element of array1 is found.
while j < n2 and element > array2[j]:
new_array.append(array2[j])
j += 1
new_array.append(element)
# If there are any remaining values in array2, that are bigger than last element in array1, then append those to
# new array.
for i in range(j,n2):
new_array.append(array2[i])
return new_array
n = len(array)
if n == 1:
return array
else:
# print('array1 = {0}, array2 = {1}'.format(array[:int(n/2)], array[int(n/2):]))
array[:int(n/2)] = merge_sort(array[:int(n/2)])
array[int(n/2):] = merge_sort(array[int(n/2):])
# print('array before joining : ',array)
array = join_sorted_arrays(array[:int(n/2)],array[int(n/2):])
# print('array after joining : ',array)
return array
Now if the code is tested,
a = [2,1,4,3,1,2,3,4,2,7,8,10,3,4]
merge_sort(a)
print(a)
out : [1, 1, 2, 2, 3, 3, 4, 2, 3, 4, 4, 7, 8, 10]
If you uncomment the print statements in the above function, you will notice that, a = given output, just before the last call of join_sorted_arrays. After this function has been called, array 'a' should be sorted. To my surprise, if I do the following, output is correct.
a = [2,1,4,3,1,2,3,4,2,7,8,10,3,4]
a = merge_sort(a)
print(a)
out : [1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 7, 8, 10]
I need some help to understand why this is happening.
I am beginner, so any other comments about coding practices etc. are also welcome.
When you reassign array as the output of join_sorted_arrays() with
array = join_sorted_arrays(array[:int(n/2)],array[int(n/2):])
you're not updating the value of a anymore.
Seeing as you pass in a as the argument array, it's understandable why all variables named array in a function might seem like they should update the original value of array (aka a). But instead, what's happening with array = join_sorted_arrays(...) is that you have a new variable array scoped within the merge_sort() function. Returning array from the function returns that new, sorted, set of values.
The reference to a was being modified up until that last statement, which is why it looks different with print(a) after merge_sort(a). But you'll only get the final, sorted output from the returned value of merge_sort().
It might be clearer if you look at:
b = merge_sort(a)
print(a) # [1, 1, 2, 2, 3, 3, 4, 2, 3, 4, 4, 7, 8, 10]
print(b) # [1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 7, 8, 10]
Note that Python isn't a pass-by-reference language, and the details of what it actually is can be a little weird to suss out at first. I'm always going back to read on how it works when I get tripped up. There are plenty of SO posts on the topic, which may be of some use to you here.
For example, this one and this one.

How to properly remove elements from array in loop using Python

I tried to remove only one element from an array and print remaining ones in a loop:
arr = [1,2,3,4,5]
for i in arr:
a = arr
a.remove(i)
print a
So I am expecting it to print this:
[2, 3, 4, 5]
[1, 3, 4, 5]
[1, 2, 3, 5]
[1, 2, 3, 4]
Why am I gettting the following results instead:
[2, 3, 4, 5]
[2, 4, 5]
[2, 4]
This is a classic problem of deep vs shallow copy.
Python copies the array by reference. So, any changes to the new variable (a in your case) will be reflected in the main array (arr). Removing element from a also remove elements from arr.
You need to use following for creating a copy.
a = arr[:]
This will not remove any elements from arr.
You've already got explanations, I'll provide an alternative - you can produce requested output without using remove at all:
arr = [1,2,3,4,5]
for i in arr:
a = [x for x in arr if x != i]
print a
(beware of non-unique elements in arr, if there are any, both this code and yours will produce unexpected results, though in different ways).
You can try this.
arr = [1, 2, 3, 4, 5, 6, 7 ]
for index, item in enumerate(arr):
print(arr[0:index] + arr[index+1:])
I think this can help you.
If you don't have any repeated value you can use this too.
for item in arr:
print(set(arr) - set([item]))
Python lists are mutable i.e. modifying operations (like list.remove()) on them do not produce a new list but modify the existing list instead so each your cycle actually permanently modifies the source list and elements are lost. You'd need to copy your whole list each time you want to modify it in order to achieve what you want, or you can create a new list with elements excluded, or, for very long lists, reconstructing by slicing is probably the most performant way:
arr = [1,2,3,4,5]
for i in range(len(arr)):
a = arr[0:i] + arr[i+1:]
print(a)

Renumbering a 1D mesh in Python

First of all, I couldn't find the answer in other questions.
I have a numpy array of integer, this is called ELEM, the array has three columns that indicate, element number, node 1 and node 2. This is one dimensional mesh. What I need to do is to renumber the nodes, I have the old and new node numbering tables, so the algorithm should replace every value in the ELEM array according to this tables.
The code should look like this
old_num = np.array([2, 1, 3, 6, 5, 9, 8, 4, 7])
new_num = np.arange(1,10)
ELEM = np.array([ [1, 1, 3], [2, 3, 6], [3, 1, 3], [4, 5, 6]])
From now, for every element in the second and third column of the ELEM array I should replace every integer from the corresponding integer specified according to the new_num table.
If you're doing a lot of these, it makes sense to encode the renumbering in a dictionary for fast lookup.
lookup_table = dict( zip( old_num, new_num ) ) # create your translation dict
vect_lookup = np.vectorize( lookup_table.get ) # create a function to do the translation
ELEM[:, 1:] = vect_lookup( ELEM[:, 1:] ) # Reassign the elements you want to change
np.vectorize is just there to make things nicer syntactically. All it does is allow us to map over the values of the array with our lookup_table.get function
I actually couldn't exactly get what your problem is but, I tried to help you as far as I could understood...
I think you need to replace, for example 2 with 1, or 7 with 10, right? In such a case, you can create a dictionary for numbers that are to be replaced. The 'dict' below is for that purpose. It could also be done by using tuples or lists but for such purposes it is better to use dictionaries. Afterwards, just replace each element by looking into the dictionary.
The code below is a very basic one is relatively easy to understand. For sure there are more pythonic ways to do that. But if you are new into Python, the code below would be the most appropriate one.
import numpy as np
# Data you provided
old_num = np.array([2, 1, 3, 6, 5, 9, 8, 4, 7])
new_num = np.arange(1,10)
ELEM = np.array([ [1, 1, 3], [2, 3, 6], [3, 1, 3], [4, 5, 6]])
# Create a dict for the elements to be replaced
dict = {}
for i_num in range(len(old_num)):
num = old_num[i_num]
dict[num] = new_num[i_num]
# Replace the elements
for element in ELEM:
element[1] = dict[element[1]]
element[2] = dict[element[2]]
print ELEM

Categories