Python - Print array of array as table - python

Given an array of array A defined as
A = [[1, 2, 3, 4], [10, 20, 30, 40], [100, 200, 300, 400]],
if print function is called
for i in range(0,3):
print A[i]
the following is the output
[1, 2, 3, 4]
[10, 20, 30, 40]
[100, 200, 300, 400].
How can I get a "prettier" output like this:
[ 1, 2, 3, 4]
[ 10, 20, 30, 40]
[100, 200, 300, 400]
???
Thank you

All you need to know is the maximum number of digits that there could be. If the number of digits is three as in your example, do this:
for i in A:
print(", ".join([str(l).rjust(3) for l in i]))
Using str(i).rjust(3) puts i right-justified in a field of width 3 where the extra characters are spaces. You could make them zeros with str(i).zfill(3), or you could make them anything you want with str(i).rjust(3, "&") for example.
Output:
1, 2, 3, 4
10, 20, 30, 40
100, 200, 300, 400
Of course, to make it applicable for more situations, you could use len(str(max(map(max, A)))) instead of hardcoding the 3.

This code will more dynamic. This will find the maximum number's length and rjust by max_len.
A = [[1, 2, 3, 4], [10, 20, 30, 40], [11100, 20033, 300, 400]]
max_len = len(str(max( max(i) for i in A)))
for i in A:
print(", ".join([str(l).rjust(max_len) for l in i]))

Why not using a numpy array for this ?
import numpy as np
print np.array(A)
[[ 1 2 3 4]
[ 10 20 30 40]
[100 200 300 400]]

You can't have those spaces in there if the record is an integer, but this code seems to split up the array nicely.
A = [1999999, 2, 3, 47678], [10, 20, 30, 40], [100, 200, 300, 400]
MaxLength=0
for i in range(0,3):
for x in A[i]:
MaxLength =len(str(x)) if MaxLength<len(str(x)) else MaxLength
for i in range(0,3):
for x in range(0,len(A[i])):
Length=MaxLength-len(str(A[i][x]))
print((" "*Length)+str(A[i][x]),end="|")
print()
If you do want, you can call this up in a definition, just do this:
def TableFormat(A):
MaxLength=0
for i in range(0,3):
for x in A[i]:
MaxLength =len(str(x)) if MaxLength<len(str(x)) else MaxLength
for i in range(0,3):
for x in range(0,len(A[i])):
Length=MaxLength-len(str(A[i][x]))
print((" "*Length)+str(A[i][x]),end="|")
print()
Then you can print the table neatly by doing TableFormat(A) with A as the array. The end="|" can be swapped for anything you want to divide the records with

Easiest way is to use two for loops
for list in A:
for element in list:
print element, '\t',
print '\n'
Try this.

Related

Seperate array into three new arrays using inequalities in Python

I am trying to split an array into three new arrays using inequalities.
This will give you an idea of what I am trying to achieve:
measurement = [1, 5, 10, 13, 40, 43, 60]
for x in measurement:
if 0 < x < 6:
small = measurement
elif 6 < x < 15:
medium = measurement
else
large = measurement
Intended Output:
small = [1, 5]
medium = [10, 13]
large = [40, 43, 60]
If your array is sorted, you can do :
measurement = [1, 5, 10, 13, 40, 43, 60]
one_third = len(measurement) // 3
two_third = (2 * len(measurement)) // 3
small = measurement[:one_third]
medium = measurement[one_third : two_thirds]
large = measurement[two_thirds:]
You could easily generalize to any number of split with a loop. Not sure if you wanted explicitly those inequalities or just split with the array in three. If its the first one, my answer is not right
You can use numpy:
arr = np.array(measurement)
small = arr[(arr>0)&(arr<6)] # array([1, 5])
medium = arr[(arr>6)&(arr<15)] # array([10, 13])
large = arr[(arr>15)] # array([40, 43, 60])
You can also use dictionary:
d = {'small':[], 'medium':[], 'large':[]}
for x in measurement:
if 0 < x < 6:
d['small'].append(x)
elif 6 < x < 15:
d['medium'].append(x)
else:
d['large'].append(x)
Output:
{'small': [1, 5], 'medium': [10, 13], 'large': [40, 43, 60]}
With the bisect module you can do something along these lines:
from bisect import bisect
breaks=[0,6,15,float('inf')]
buckets={}
m = [1, 5, 10, 13, 40, 43, 60]
for e in m:
buckets.setdefault(breaks[bisect(breaks, e)], []).append(e)
You then have a dict of lists matching what you are looking for:
>>> buckets
{6: [1, 5], 15: [10, 13], inf: [40, 43, 60]}
You can also form tuples of your break points and list that will become a dict to form the sub lists:
m = [1, 5, 10, 13, 40, 43, 60]
buckets=[('small',[]), ('medium',[]), ('large',[]), ('other',[])]
breaks=[(0,6),(6,15),(15,float('inf'))]
for x in m:
buckets[
next((i for i,t in enumerate(breaks) if t[0]<=x<t[1]), -1)
][1].append(x)
>>> dict(buckets)
{'small': [1, 5], 'medium': [10, 13], 'large': [40, 43, 60], 'other': []}

Python : why results are same when i put int or list or tuple in list?

>>> aa = [10, 20, 30]
>>> aa[1:2] = 100, 200
[10, 100, 200, 30]
>>> aa = [10, 20, 30]
>>> aa[1:2] = [100, 200]
[10, 100, 200, 30]
>>> aa = [10, 20, 30]
>>> aa[1:2] = (100, 200)
[10, 100, 200, 30]
I'm a beginner to Python. I tried to change 20 into 100, 200, so I tried 3 ways of inserting these 2 numbers: ints, a list, and a tuple. Why is the result the same when I insert ints or a list or a tuple in aa[1:2]?
By using aa[1:2], you are modifying a list item using slice assignment. Slice assignment replaces the specified item (or items), in this case the second item in aa, with whatever new item(s) that is specified. I'll go through each type to clarify what is happening
Ints - aa[1:2] = 100, 200: this example is the most clear. We are replacing aa[1:2] with two ints that go into the list in that spot.
List/Tuple: this example of how slice assignment works -- instead of adding a list to the list, it extends the new list into the old list. The tuple works the same way. To replace the item and add a list or tuple, wrap the list or tuple in another list first:
>>> aa = [10, 20, 30]
>>> aa[1:2] = [[100, 200]]
[10, [100, 200], 30]
>>> aa = [10, 20, 30]
>>> aa[1:2] = [(100, 200)]
[10, (100, 200), 30]

How to print the sum of the current and previous element in a list

I am trying to iterate through a list of numbers and print the sum of the current element and the previous element using python. For example,
Given numbers = [5,10,15,20,25,30,30], the output should be 5, 15, 25, 35, 45, 55, 60,. This is the following code that I have tried, it is very close to the answer but the first element is wrong.
numbers = [5, 10, 15, 20, 25, 30, 30]
i = 0
for x in range(1, 8):
print(numbers[i] + numbers[i - 1], end=", ")
i += 1
I am getting the output 35, 15, 25, 35, 45, 55, 60,. What am I doing wrong?
You can pair adjacent items of numbers by zipping it with itself but padding one with a 0, so that you can iterate through the pairs to output the sums in a list comprehension:
[a + b for a, b in zip([0] + numbers, numbers)]
or by mapping the pairs to the sum function:
list(map(sum, zip([0] + numbers, numbers)))
Both would return:
[5, 15, 25, 35, 45, 55, 60]
You are starting at index 0, where it seems your intended output starts at index 1:
Here is a better solution:
numbers = [5, 10, 15, 20, 25, 30, 30]
for i in range(len(numbers)):
if i == 0:
print(numbers[i])
else:
print(numbers[i - 1] + numbers[i])
Outputs:
5
15
25
35
45
55
60
This should work:
numbers = [5, 10, 15, 20, 25, 30, 30]
output = [numbers[i]+numbers[i-1] if i > 0 else numbers[i] for i in range(len(numbers))]
print(output)
You are starting at i = 0, so the first number you are adding is the 0 and the -1 (the last one, in this case). That's why you are getting the 35 (5+30).
This list comprehension works:
numbers = [5, 10, 15, 20, 25, 30, 30]
output = [value + numbers[i-1] if i else value for i, value in enumerate(numbers)]
print(output)
>>> [5, 15, 25, 35, 45, 55, 60]
Cheat, and add a [0] at the start to prevent the first sum to be wrong.
You'll run into problems at the end, though, because then the list in the enumerate is one item longer than the original, so also clip off its last number:
print ([a+numbers[index] for index,a in enumerate([0]+numbers[:-1])])
Result:
[5, 15, 25, 35, 45, 55, 60]
If you want to see how it works, print the original numbers before addition:
>>> print ([(a,numbers[index]) for index,a in enumerate([0]+numbers[:-1])])
[(0, 5), (5, 10), (10, 15), (15, 20), (20, 25), (25, 30), (30, 30)]
The enumerate loops over the changed list [0, 5, 15, .. 55], where everything is shifted up a place, but numbers[index] still returns the correct index from the original list. Adding them up yields the correct result.

Search a number in a sorted 2D array

I'm trying to find the number that I'm looking from in a 2D array list. However, it has to be sorted first before searching.
Everything seems to be working fine when I'm trying to find a number in the 2D array. It is just the fact of sorting the 2D array in a way that will still be working. Let's assume I want to sort a 3x3 2D array. The way that it should display is:
[[8, 27, 6],
[1, 0, 11],
[10, 9, 3]]
Then, I will be looking for a number by using the binary search method through the sorted 2D array. My mid value will be in the middle of the array from the search.
This is just an example, but what I want to accomplish when I put randomized numbers and then sort row and columns. Using this idea, I'm using the random.randint() library from Python to randomized my numbers. Then, I'm trying to sort afterward in my 2d array, but it isn't really sorting before continuing.
n = 5
m = 5
def findnum_arr(array, num):
low = 0
high = n * m - 1
while (high >= low):
mid = (low + high) // 2
i = mid // m
j = mid % m
if (num == array[i][j]):
return True
if (num < array[i][j]):
high = mid - 1
else:
low = mid + 1
return False
if __name__ == '__main__':
multi_array = [[random.randint(0, 20) for x in range(n)] for y in range(m)]
sorted(multi_array)
Sorted:
[[0, 1, 3],
[6, 8, 9],
[10, 11, 27]]
Should be the sorted 2D array. Is it possible that both the row and column are sorted respectively with the sorted function?
Calling sorted on a nested list that is just going to sort based on the first index in the list.
Example:
arr = [[8, 27, 6],[1, 0, 11],[10, 15, 3], [16, 12, 14], [4, 9, 13]]
is going to return
[[1, 0, 11], [4, 9, 13], [8, 27, 6], [10, 15, 3], [16, 12, 14]]
To do this way that you want, you are going to have to flatten and then reshape.
To do this, I would try introducing numpy.
import numpy as np
a = np.array(sorted(sum(arr, [])))
#sorted(sum(arr, [])) flattens the list
b = np.reshape(a, (-1,3)).tolist()
EDITED FOR CLARITY: You can use your m and n as parameters in np.reshape. The first parameter (m) would return the number of arrays, while (n) would return the number of arrays.
The use of -1 in either parameter means that the reshaped array will be fit to return the requirements of the other parameter.
b would return
[[0, 1, 3], [4, 6, 8], [9, 10, 11], [12, 13, 14], [15, 16, 27]]
Finally found out a proper solution without using numpy and avoiding sum() module.
if __name__ == '__main__':
x = 7
multi_array = [[random.randint(0, 200) for x in range(n)] for y in range(m)]
# one_array = sorted(list(itertools.chain.from_iterable(multi_array))) Another way if you are using itertools
one_array = sorted([x for row in multi_array for x in row])
sorted_2d = [one_array[i:i+m] for i in range(0, len(one_array), n)]
print("multi_array list is: \n{0}\n".format(multi_array))
print("sorted 2D array: \n{0}\n".format(sorted_2d))
if not findnum_arr(sorted_2d, x):
print("Not Found")
else:
print("Found")
output:
multi_array list is:
[[40, 107, 23, 27, 42], [150, 84, 108, 191, 172], [154, 22, 161, 26, 31], [18, 150, 197, 77, 191], [96, 124, 81, 1
25, 186]]
sorted 2D array:
[[18, 22, 23, 26, 27], [31, 40, 42, 77, 81], [84, 96, 107, 108, 124], [125, 150, 150, 154, 161], [172, 186, 191, 1
91, 197]]
Not Found
I wanted to find a standard library module where I could flat the 2D array into 1D and sort it. Then, I would make a list comprehension of my 1D array and build it into a 2D array to. This sounds a lot of works but seems to work fine. Let me know if there is a better way to do it without numpy and faster :)

How can I do some matrix addition in rethinkDB?

So essentially I have this variable question[1]
where question[1] is: [[1, 0, 0], [1, 0, 0], [0,1,0] ...]
I want to be able to add them vertically so I get one array like so
[1,0,0]+[1,0,0]=[2,0,0] + [0,1,0] = [2,1,0] + ....
Additionally, the arrays might be longer or shorter (but will be at least two long)
How could I do this?
The API Doc has the following example:
sequence1 = [100, 200, 300, 400]
sequence2 = [10, 20, 30, 40]
sequence3 = [1, 2, 3, 4]
r.map(sequence1, sequence2, sequence3,
lambda val1, val2, val3: (val1 + val2 + val3)).run(conn)
with result:
[111, 222, 333, 444]
But this won't account for a variable amount of inputs as I want. Answer in python please!
From #mglukov
r.expr([[100, 200, 300, 400],[10, 20, 30, 40],[1, 2, 3, 4]]).reduce((left,right) => {
return left.map(right, (leftVal, rightVal) => { return leftVal.add(rightVal); });
})
Good question!

Categories

Resources