Print a two dimension list with format in Python - python

So I have defined a two dimension list in python using:
column = 3
row = 2
Matrix = [['' for i in range(column)] for j in range(row)]
Then I started adding values to it:
Matrix[0][0] += 'A'
Matrix[1][0] += 'AB'
Matrix[2][0] += 'ABC'
Matrix[0][1] += 'X'
Matrix[1][1] += 'XY'
Matrix[2][1] += 'XYZ'
Then I started printing with hope of some sort of format:
for i in range(0, row, 1):
for j in range(0, column, 1):
print(Matrix[i][j] + '\t')
I was thinking of get result like
A AB ABC
X XY XYZ
But actually I got:
A
AB
ABC
X
XY
XYZ
Just wondering what is wrong with my code...

the print function adds a newline to the end.
a way to signal that you dont want a new line is to use add a comma at the end
Python 3
print(Matrix[i][j],"\t",)
Python 2.7
print Matrix[i][j],"\t",

You only want a new line each i, and not each j. Generally they're implicit, so you need to specify no newline:
Python 3:
for i in range(0, row, 1):
for j in range(0, column, 1):
print(Matrix[i][j] + '\t', end="") # <-- end="" means no newline
print('') # <-- implicit newline, only in row loop
Python 2:
for i in range(0, row, 1):
for j in range(0, column, 1):
print Matrix[i][j] + '\t', # <-- comma at the end means no newline
print('') # <-- implicit newline, only in row loop

You can use the sep argument in python3:
for row in zip(*Matrix):
print(*row, sep='\t')
You have the rows as columns in your matrix, so you'll need to zip it to get at the rows first.
Then, you can print the individual elements in the row, with a TAB between them
In python2, this would be:
import itertools
for row in itertools.izip(*Matrix):
print('\t'.join(row))

First you may want to check how you added your values. While
iterating over the row, you will receive an 'IndexError: list out of range'
Adding your values should look like this:
Matrix[0][0] = 'A'
Matrix[0][1] = 'AB'
Matrix[0][2] = 'ABC'
Matrix[1][0] = 'X'
Matrix[1][1] = 'XY'
Matrix[1][2] = 'XYZ'
After that, then all you have to do is iterate over your rows using the method join() on each row.
for i in range(row):
print '\t'.join(Matrix[i])
That will print your desired result:
A AB ABC
X XY XYZ

Related

How to make the two different code outputs appear in the same area?

I am trying to merge two outputs together so that it appears something like this:
0 1 2
0 ? ? ?
1 ? ? ?
2 ? ? ?
But it ended up appearing like this instead:
0 1 2
0
1
? ? ?
? ? ?
I tried this to make the codes appear but i have no idea how to place their outputs together
import random
rows = [3]
columns = [4]
def rowscol():
for j in range(columns[0]):
print(" " * 1, end="")
print(j, end="")
print()
for i in range(rows[0]):
print(i)
rowscol()
def create_game_board(rows, columns):
board = [[random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ") for _ in range(columns[0])] for _ in range(rows[0])]
# If number of cells is odd, make the last cell an unused cell
if (rows[0] * columns[0]) % 2 != 0:
board[-1][-1] = "#"
return board
board = create_game_board(rows,columns)
# Function to display the game board
def display_board(board):
pad = " " * 30
for row in board:
line = pad + " ".join('?' if column != '#' else '#' for column in row)
print(line)
display_board(board)
Welcome to StackOverflow!
When using multidimensional arrays, like in your case a list of lists, I like to be able to index into them easily. Because of this I usually change it to a dict and use the coordiantes as keys. This way you can even store additional information about the board, like the dimension sizes or anything else.
I added a bunch of comments to explain how the code works but feel free to ask if anything isn't clear:
import random
import string
def create_game_board(rows, cols):
board = dict()
# save dimensions inside the dict itself
board['cols'] = cols
board['rows'] = rows
for y in range(rows):
for x in range(cols):
# add random letter to board at (x,y)
# x,y makes a tuple which can be a key in a dict
# changed to use string.ascii_uppercase so that you don't forget any letter
board[x, y] = random.choice(string.ascii_uppercase)
# change last element to # when both dimensions are odd
if (rows * cols) % 2 == 1:
board[rows-1, cols-1] = "#"
return board
def display_board(board):
# get dimensions
cols, rows = board['cols'], board['rows']
# print header
print(' '.join([' '] + [str(x) for x in range(cols)]))
for y in range(rows):
# print rows
#print(' '.join([str(y)] + [board[x, y] for x in range(cols)])) # to display the actual letter at this location
print(' '.join([str(y)] + ['?' if board[x, y] == '#' else '#' for x in range(cols)])) # using your display function
print() # separator empty line
board = create_game_board(3, 3)
display_board(board)
The output is nothing special when I'm using your method of printing, you might need to change that, I'm not sure how you wanted to display it. I added a line that allows you to print the values on those coordinates.
This is the output:
0 1 2
0 # # #
1 # # #
2 # # ?
Maybe something like?
def draw_board(board):
print(" " + " ".join([str(i) for i in range(len(board[0]))])) # print column numbers
for i in range(len(board)):
row = ""
for j in range(len(board[i])):
row += board[i][j] + " "
print(str(i) + " " + row)
draw_board(board)

Not Parsing Through

I tried to parse through a text file, and see the index of the character where the four characters before it are each different. Like this:
wxrgh
The h would be the marker, since it is after the four different digits, and the index would be 4. I would find the index by converting the text into an array, and it works for the test but not for the actually input. Does anyone know what is wrong.
def Repeat(x):
size = len(x)
repeated = []
for i in range(_size):
k = i + 1
for j in range(k, _size):
if x[i] == x[j] and x[i] not in repeated:
repeated.append(x[i])
return repeated
with open("input4.txt") as f:
text = f.read()
test_array = []
split_array = list(text)
woah = ""
for i in split_array:
first = split_array[split_array.index(i)]
second = split_array[split_array.index(i) + 1]
third = split_array[split_array.index(i) + 2]
fourth = split_array[split_array.index(i) + 3]
test_array.append(first)
test_array.append(second)
test_array.append(third)
test_array.append(fourth)
print(test_array)
if Repeat(test_array) != []:
test_array = []
else:
woah = split_array.index(i)
print(woah)
print(woah)
I tried a test document and unit tests but that still does not work
You can utilise a set to help you with this.
Read the entire file into a list (buffer). Iterate over the buffer starting at offset 4. Create a set of the 4 characters that precede the current position. If the length of the set is 4 (i.e., they're all different) and the character at the current position is not in the set then you've found the index you're interested in.
W = 4
with open('input4.txt') as data:
buffer = data.read()
for i in range(W, len(buffer)):
if len(s := set(buffer[i-W:i])) == W and buffer[i] not in s:
print(i)
Note:
If the input data are split over multiple lines you may want to remove newline characters.
You will need to be using Python 3.8+ to take advantage of the assignment expression (walrus operator)

Print index of row and column in adjacency matrix

I have a function to build adjacency matrix. I want to improve matrix readability for humans, so I decided to print row index like this:
Now I want to print column index in the same way, but I can't do it properly. best result I get is this:
Any Ideas and suggestions how i can print column indexes neatly?
Source code here.
def generate_adjacency_matrix(vertices):
# Create empty Matrix
matrix = [['.' for _ in range(len(vertices))] for _ in range(len(vertices))]
# Fill Matrix
for row in range(len(matrix)):
for num in range(len(matrix)):
if num in vertices[row]:
matrix[row][num] = '1'
# Print column numbers
numbers = list(range(len(matrix)))
for i in range(len(numbers)):
numbers[i] = str(numbers[i])
print(' ', numbers)
#Print matrix and row numbers
for i in range(len(matrix)):
if len(str(i)) == 1:
print(str(i) + ' ', matrix[i])
else:
print(i, matrix[i])
If it matters Parameter in my function is a dictionary that looks like:
{0:[1],
1:[0,12,8],
2:[3,8,15]
....
20:[18]
}
If you know you're only going to 20, then just pad everything to 2 chars:
For the header row:
numbers[i] = str(numbers[i].zfill(2))
For the other rows, set to ". " or ".1" or something else that looks neat.
That would seem to be the easiest way.
Alternative way is to have 2 column headers, one above the other, first one is the tens value, second is the unit value. That allows you to keep the width of 1 in the table as well, which maybe you need.

How to find duplicates in a python list that are adjacent to each other and list them with respect to their indices?

I have a program that reads a .csv file, checks for any mismatch in column length (by comparing it to the header-fields), which then returns everything it found out as a list (and then writes it into a file). What I want to do with this list, is to list out the results as follows:
row numbers where the same mismatch is found : the amount of columns in that row
e.g.
rows: n-m : y
where n and m are the numbers of rows which share the same amount of columns that mismatch to header.
I have looked into these topics, and while the information is useful, they do not answer the question:
Find and list duplicates in a list?
Identify duplicate values in a list in Python
This is where I am right now:
r = csv.reader(data, delimiter= '\t')
columns = []
for row in r:
# adds column length to a list
colm = len(row)
columns.append(colm)
b = len(columns)
for a in range(b):
# checks if the current member matches the header length of columns
if columns[a] != columns[0]:
# if it doesnt, write the row and the amount of columns in that row to a file
file.write("row " + str(a + 1) + ": " + str(columns[a]) + " \n")
the file output looks like this:
row 7220: 0
row 7221: 0
row 7222: 0
row 7223: 0
row 7224: 0
row 7225: 1
row 7226: 1
when the desired end result is
rows 7220 - 7224 : 0
rows 7225 - 7226 : 1
So I what I essentially need, the way i see it, is an dictionary where key is the rows with duplicate value and value is the amount of columns in that said mismatch. What I essentially think I need (in a horrible written pseudocode, that doesn't make any sense now that I'm reading it years after writing this question), is here:
def pseudoList():
i = 1
ListOfLists = []
while (i < len(originalList)):
duplicateList = []
if originalList[i] == originalList[i-1]:
duplicateList.append(originalList[i])
i += 1
ListOfLists.append(duplicateList)
def PseudocreateDict(ListOfLists):
pseudoDict = {}
for x in ListOfLists:
a = ListOfLists[x][0] #this is the first node in the uniqueList created
i = len(ListOfLists) - 1
b = listOfLists[x][i] #this is the last node of the uniqueList created
pseudodict.update('key' : '{} - {}'.format(a,b))
This however, seems very convoluted way for doing what I want, so I was wondering if there's a) more efficient way b) an easier way to do this?
You can use a list comprehension to return a list of elements in the columns list that differ from adjacent elements, which will be the end-points of your ranges. Then enumerate these ranges and print/write out those that differ from the first (header) element. An extra element is added to the list of ranges to specify the end index of the list, to avoid out of range indexing.
columns = [2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 2, 1];
ranges = [[i+1, v] for i,v in enumerate(columns[1:]) if columns[i] != columns[i+1]]
ranges.append([len(columns),0]) # special case for last element
for i,v in enumerate(ranges[:-1]):
if v[1] != columns[0]:
print "rows", v[0]+1, "-", ranges[i+1][0], ":", v[1]
output:
rows 2 - 5 : 1
rows 6 - 9 : 0
rows 10 - 11 : 1
rows 13 - 13 : 1
You can also try the following code -
b = len(columns)
check = 0
for a in range(b):
# checks if the current member matches the header length of columns
if check != 0 and columns[a] == check:
continue
elif check != 0 and columns[a] != check:
check = 0
if start != a:
file.write("row " + str(start) + " - " + str(a) + ": " + str(columns[a]) + " \n")
else:
file.write("row " + str(start) + ": " + str(columns[a]) + " \n")
if columns[a] != columns[0]:
# if it doesnt, write the row and the amount of columns in that row to a file
start = a+1
check = columns[a]
What you want to do is a map/reduce operation, but without the sorting that is normally done between the mapping and the reducing.
If you output
row 7220: 0
row 7221: 0
row 7222: 0
row 7223: 0
To stdout, you can pipe this data to another python program that generates the groups you want.
The second python program could look something like this:
import sys
import re
line = sys.stdin.readline()
last_rowid, last_diff = re.findall('(\d+)', line)
for line in sys.stdin:
rowid, diff = re.findall('(\d+)', line)
if diff != last_diff:
print "rows", last_rowid, rowid, last_diff
last_diff = diff
last_rowid = rowid
print "rows", last_rowid, rowid, last_diff
You would execute them like this in a unix environment to get the output into a file:
python yourprogram.py | python myprogram.py > youroutputfile.dat
If you cannot run this on a unix environment, you can still use the algorithm I wrote in your program with a few modifications.

formatting list to convert into string

Here is my question
count += 1
num = 0
num = num + 1
obs = obs_%d%(count)
mag = mag_%d%(count)
while num < 4:
obsforsim = obs + mag
mylist.append(obsforsim)
for index in mylist:
print index
The above code gives the following results
obs1 = mag1
obs2 = mag2
obs3 = mag3
and so on.
obsforrbd = parentV = {0},format(index)
cmds.dynExpression(nPartilce1,s = obsforrbd,c = 1)
However when i run the code above it only gives me
parentV = obs3 = mag3
not the whole list,it only gives me the last element of the list why is that..??
Thanks.
I'm having difficulty interpreting your question, so I'm just going to base this on the question title.
Let's say you have a list of items (they could be anything, numbers, strings, characters, etc)
myList = [1,2,3,4,"abcd"]
If you do something like:
for i in myList:
print(i)
you will get:
1
2
3
4
"abcd"
If you want to convert this to a string:
myString = ' '.join(myList)
should have:
print(myString)
>"1 2 3 4 abcd"
Now for some explanation:
' ' is a string in python, and strings have certain methods associated with them (functions that can be applied to strings). In this instance, we're calling the .join() method. This method takes a list as an argument, and extracts each element of the list, converts it to a string representation and 'joins' it based on ' ' as a separator. If you wanted a comma separated list representation, just replace ' ' with ','.
I think your indentations wrong ... it should be
while num < 4:
obsforsim = obs + mag
mylist.append(obsforsim)
for index in mylist:
but Im not sure if thats your problem or not
the reason it did not work before is
while num < 4:
obsforsim = obs + mag
#does all loops before here
mylist.append(obsforsim) #appends only last
The usual pythonic way to spit out a list of numbered items would be either the range function:
results = []
for item in range(1, 4):
results.append("obs%i = mag_%i" % (item, item))
> ['obs1 = mag_1', 'obs2 = mag_2', 'ob3= mag_3']
and so on (note in this example you have to pass in the item variable twice to get it to register twice.
If that's to be formatted into something like an expression you could use
'\n'.join(results)
as in the other example to create a single string with the obs = mag pairs on their own lines.
Finally, you can do all that in one line with a list comprehension.
'\n'.join([ "obs%i = mag_%i" % (item, item) for item in range (1, 4)])
As other people have pointed out, while loops are dangerous - its easier to use range

Categories