list organized into columns not rows - python

I have a list of lists that I am trying to write to columns instead of rows. My list looks like this:
['31 32 31 8', '31 31 32 8', '31 31 31 8', '31 32 31 31']
I want it to llok like this:
31 31 31 31
32 31 31 32
31 32 31 31
8 8 8 31
I can get a nice print in rows like this:
with open("text.csv", 'w') as f:
for x in zip(contents):
f.write('\t'.join(x)+'\n')
What I would like to do is get this data in columns

You may use zip() for this. Firstly convert your list of string to list of list using str.split(), then iterate over ziped list. Below is the sample code:
>>> my_list = ['31 32 31 8', '31 31 32 8', '31 31 31 8', '31 32 31 31']
>>> my_list_list = [s.split() for s in my_list]
>>> for item in zip(*my_list_list):
... print item
...
('31', '31', '31', '31')
('32', '31', '31', '32')
('31', '32', '31', '31')
('8', '8', '8', '31')

Alternatively, numpy is really good for this kind of stuff.
If you have
test = numpy.array([[31,32,31,8], [31,31,32,8], [31,31,31,8], [31,32,31,31]]
then you can access the first column by saying
test[:,0] which returns array([31, 31, 31, 31])

Use the csv module to output the data once you've massaged it into shape with zip():
import csv
# data is a list of lists
data = [s.split() for s in ['31 32 31 8', '31 31 32 8', '31 31 31 8', '31 32 31 31']]
with open('text.csv', 'w') as f:
writer = csv.writer(f, delimiter='\t')
writer.writerows(zip(*data))
This results in a CSV file which uses tab as the delimiter that looks like this:
31 31 31 31
32 31 31 32
31 32 31 31
8 8 8 31

Related

How to reduce these code? for every length I'm using a if statement?

My code
cummulative_num = [['1', '4', '5', '7'], ['2', '5', '6', '9']]
if len(cumulative_num)==1:
print(*cumulative_num[0])
out=""
if len(cumulative_num)==2:
for i in cumulative_num[0]:
for j in cumulative_num[1]:
out+= i+j+ " "
print(out)
out=""
if len(cumulative_num)==3:
for i in cumulative_num[0]:
for j in cumulative_num[1]:
for k in cumulative_num[2]:
out+= i+j+k+ " "
print(out)
output : 12 15 16 19 42 45 46 49 52 55 56 59 72 75 76 79
The output order should be
each first array element is added to every element in the second array
Please provide me a better approach when the array in cumulative_num increases.
Something like this could work:
The * unpacks the lists into product, no matter how many sublists you may have.
from itertools import product
cummulative_num = [['1', '4', '5', '7'], ['2', '5', '6', '9']]
' '.join([''.join(x) for x in product(*cummulative_num)])
Output
'12 15 16 19 42 45 46 49 52 55 56 59 72 75 76 79'
This code is nothing fancy, but it works well and can be adapted well depending on if you want the data stored.
output = [] #Optional
for i in cummulative_num[0]:
for j in cummulative_num[1]:
output.append(f'{i}{j}') #Optional
print(f'{i}{j}')

Splitting multiple, spaced-list values in Python [duplicate]

This question already has answers here:
Apply function to each element of a list
(4 answers)
How do I make a flat list out of a list of lists?
(34 answers)
Closed 1 year ago.
I have a very simple list where it looks like this:
['20 32 35 47 64', '15 17 25 32 53', '07 10 12 61 65', '08 14 31 58 68', '01 10 44 47 56']
What I would like to do is to split the values within each list where the values are displayed as follows:
[20,32,35,47,64,15,17,25,32,53,07,10,12,61,65,..]
myvallist = myvalues.split(" ")
print (myvallist)
For some reason, when I attempt to use the .split(), pyCharm is throwing an error.
Traceback (most recent call last):
File "C:\Users\VFARETR.CENTRAL\Desktop\pyCharm\megaTest", line 25, in <module>
myvallist = myvalues.split(" ")
AttributeError: 'list' object has no attribute 'split'
Any help would be great!
You're trying to split the list, not the string. Try this:
input_list = ['20 32 35 47 64', '15 17 25 32 53', '07 10 12 61 65', '08 14 31 58 68', '01 10 44 47 56']
complete_list = []
for sub_list in input_list:
current_items = sub_list.split()
complete_list.extend([i for i in current_items])
It says so because your list consists of strings. You have to acces the string inside the list before you split the string.
mylist = ['20 32 35 47 64', '15 17 25 32 53', '07 10 12 61 65',
'08 14 31 58 68', '01 10 44 47 56']
myvallist = []
for item in mylist:
myvallist += item.split(' ') # adds the numbers of the current string to myvallist
print(myvallist)
I don't know if you want the entries to be integers or strings but here's a solution with them as strings.
my_list = ['20 32 35 47 64', '15 17 25 32 53', '07 10 12 61 65', '08 14 31 58 68', '01 10 44 47 56']
my_new_list = [item for sublist in [item.split(" ") for item in my_list] for item in sublist]
The inner list comprehension splits each string by spaces and then the outer list comprehension then flattens the array produced.

Python exercise about finding indices of X in the list

def leesFormulier(l1):
index = 0
lres = []
for j in range(len(l1)):
for k in range(0,9,2):
if l1[j][k] == 'X':
lres.append(index+1)
index += 1
else:
index += 1
return lres
print(leesFormulier(l1 = ['1 X 3 4 X', 'X 7 X X 10', '11 12 13 14 15', '16 17 18 19 20', '21 22 23 24 25', '26 27 28 29 30', '31 32 33 34 35', '36 37 38 39 40', '41 42 43 44 X']))
result : [2, 5, 6, 8, 9]
Hello everybody,
I'm making an exercise on Python and I have to find the indices of where you can find the 'X'. And I solved it for the most part but the only problem I'm having is the last 'X' that won't be recognized. I put it in Pythontutor and there I could see that on the last time going through the for loops that it goes to the last k for loop but it doesn't check it but instead goes immediately to the j for lus and then ends the iteration and goes to the return part. I don't know what I'm doing wrong, would appreciate it if somebody could help me out.
Thanks in advance!
Don't need all those indexes or nested loops for this problem and you can simplify it a lot
def lessFromulier(l1):
lres = []
new_string = " ".join(l1).split(" ")
for i, letter in enumerate(new_string):
if letter == "X":
lres.append(i+1)
return lres
test = [
"1 X 3 4 X",
"X 7 X X 10",
"11 12 13 14 15",
"16 17 18 19 20",
"21 22 23 24 25",
"26 27 28 29 30",
"31 32 33 34 35",
"36 37 38 39 40",
"41 42 43 44 X",
]
print(lessFromulier(test))
which gives this output
[2, 5, 6, 8, 9, 45]
Your input is really weird to me, but here is a solution to your question
def leesFormulier(l1):
index = 0
lres = []
for i in range(len(l1)):
for j in range(len(l1[i])):
c = l1[i][j]
if c == ' ':
continue
if c == 'X':
index += 1
lres.append(index)
else:
index += 1
return lres
print(leesFormulier(l1 = ['1 X 3 4 X', 'X 7 X X 10', '11 12 13 14 15', '16 17 18 19 20', '21 22 23 24 25', '26 27 28 29 30', '31 32 33 34 35', '36 37 38 39 40', '41 42 43 44 X']))

How to search in a list across more elements unified in a single string and return the position?

I have a list like the following:
['56', '33 f6', '39 74 24 0c', '57', '74 07', '68 1c e0 40 00', 'eb 05', '68 18 e0 40 00', '68 10 e0 40 00', 'ff 15 18 81 40 00', '8b f8', '59', '3b fe', '59', '75 04', '33 c0']
Let's say I want to search for a sequence as:
'33 f6 39 74 24 0c 57 74' and then know which elements of the list are covered. In this case it would be position 2,3,4,5.
I thought of unifying the list in one string and do the search through find(). But I wouldn't know how to go forward.
Is there a better way to do this in Python?
EDIT: The solution accepted worked perfectly!
Shortest version I could come up with:
arr = ['56', '33 f6', '39 74 24 0c', '57', '74 07', '68 1c e0 40 00', 'eb 05', '68 18 e0 40 00', '68 10 e0 40 00', 'ff 15 18 81 40 00', '8b f8', '59', '3b fe', '59', '75 04', '33 c0']
search_term = '33 f6 39 74 24 0c 57 74'
joined = ' '.join(arr)
search_index = joined.find(search_term)
contained_indices = []
counter = 0
for i in range(len(arr)):
if counter >= search_index and counter <= search_index + len(search_term):
contained_indices.append(i)
if counter >= search_index + len(search_term):
break
counter += len(arr[i])+1
print(contained_indices)
Note that it uses 0-based indexing and it will probably fail if you do not have the neat structure in your current array anymore.

Why is it printing 4 instead of 3 numbers for first part?

l = open(filename)
string = l.read()
subsetA, subsetB = string[:len(string)//2], string[len(string)//2:]
print(subsetA)
print(subsetB)
It keeps printing this:
9 17 4 8
11 18 13
I am expecting to get:
9 17 4
8 11 18 13
The textfile:
9 17 4 8 11 18 13
Any help? Thank you! I still don't understand why I am doing wrong this part:
subsetA, subsetB = string[:len(string)//2], string[len(string)//2:]
You are splitting a string of length 18 in two:
>>> text = '9 17 4 8 11 18 13\n'
>>> len(text) // 2
9
>>> text[:9]
'9 17 4 8 '
>>> text[9:]
'11 18 13\n'
so the division makes perfect sense.
Even without the newline at the end, making it length 17, would still work:
>>> text = '9 17 4 8 11 18 13'
>>> len(text)
17
>>> len(text) // 2
8
>>> text[:8]
'9 17 4 8'
>>> text[8:]
' 11 18 13'
You are not dividing the string in half based on the number of groups of digits here, you are splitting purely on the number of string characters.
If you wanted to do that, split the line first:
>>> parts = text.split()
>>> parts
['9', '17', '4', '8', '11', '18', '13']
>>> parts[:len(parts)//2]
['9', '17', '4']
>>> parts[len(parts)//2:]
['8', '11', '18', '13']

Categories