My result data is in a list of tuples, which each have a list in them:
[(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], ['I', 'J', 'K', 'L', 'M', 'N']),
...
(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], ['I', 'J', 'K', 'L', 'M', 'N'])]
What's the best way to strip all the nesting and quotes and write A:N to a tab delimited file?
The quotes are not part of the string, they denote the string. You would not be able to remove them.
The csv module makes this taks pretty straightforward:
import csv, itertools
with open('file.csv', 'wb') as f:
writer = csv.writer(f, delimiter="\t")
writer.writerows(list(itertools.chain(*t)) for t in results)
This results in a file where each row corresponds to a tuple and a row contains the letters of both lists, separated by tabs.
Recursive is the natural way to solve this issue.
let target be your list [([A,B..]), ([A, B])]
def dump(target):
for obj in target:
if isinstance(obj,tuple) or isinstance(obj, list):
dump(obj)
else:
print(obj),
dump(target)
print()
Related
I have been racking my brain and scouring the internet for some hours now, please help.
Effectively I am trying to create a self-contained function (in python) for producing a caesar cipher. I have a list - 'cache' - of all letters A-Z.
def caesarcipher(text, s):
global rawmessage #imports a string input - the 'raw message' which is to be encrypted.
result = ''
cache = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
Is it possible to analyze the string input (the 'rawmessage') and attribute each letter to its subsequent index position in the list 'cache'? e.g. if the input was 'AAA' then the console would recognise it as [0,0,0] in the list 'cache'. Or if the input was 'ABC' then the console would recognise it as [0,1,2] in the list 'cache'.
Thank you to anyone who makes the effort to help me out here.
Use a list comprehension:
positions = [cache.index(letter) for letter in rawmessage if letter in cache]
You can with a list comprehension. Also you can get the letter from string.
import string
print([string.ascii_uppercase.index(c) for c in "AAA"])
# [0, 0, 0]
print([string.ascii_uppercase.index(c) for c in "ABC"])
# [0, 1, 2]
result = []
for i in list(rawmessage):
result.append(cache.index(i))
I'm trying to replace the characters of the reversed alphabet with those of the alphabet. This is what I've got:
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
rev_alphabet = alphabet[::-1]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
def f(alph, rev_alph):
return (alph, rev_alph)
char_list_of_tups = list(map(f, alphabet, rev_alphabet))
for alph, rev_alph in char_list_of_tups:
sample = sample.replace(rev_alph, alph)
print(sample)
expected output: did you see last night's episode?
actual output: wrw you svv ozst nrtst's vprsowv?
I understand that I'm printing the last "replacement" of the whole iteration. How can I avoid this without appending it to a list and then running into problems with the spacing of the words?
Your problem here is that you lose data as you perform each replacement; for a simple example, consider an input of "az". On the first replacement pass, you replace 'z' with 'a', and now have "aa". When you get to replacing 'a' with 'z', it becomes "zz", because you can't tell the difference between an already replaced character and one that's still unchanged.
For single character replacements, you want to use the str.translate method (and the not strictly required, but useful helper function, str.maketrans), to do character by character transliteration across the string in a single pass.
from string import ascii_lowercase # No need to define the alphabet; Python provides it
# You can use the original str form, no list needed
# Do this once up front, and reuse it for as many translate calls as you like
trans_map = str.maketrans(ascii_lowercase[::-1], ascii_lowercase)
sample = sample.translate(trans_map)
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
# or
alphabet = [chr(97 + i) for i in range(0,26)]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
res = []
for ch in sample:
if ch in alphabet:
res.append(alphabet[-1 - alphabet.index(ch)])
else:
res.append(ch)
print("".join(res))
Another Way if you are ok with creating a new string instead.
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
dictRev = dict(zip(alphabet, alphabet[::-1]))
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
s1="".join([dictRev.get(char, char) for char in sample])
print(s1)
"did you see last night's episode?"
If I have two lists of individual string characters:
['H', 'e', 'l', 'l', 'o']
['w', 'o', 'r', 'l', 'd']
How do I make the final outcome look like this below of one list and where all of the string characters are combined:
['Hello','world']
If I try something like this:
word1join = "".join(word1)
word2join = "".join(word2)
print(word1join,type(word1join))
print(word2join,type(word1join))
print(list(word1join + word2join))
I am recreating the original data structure again but incorrectly, any tips appreciated!
Hello <class 'str'>
world <class 'str'>
['H', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
Just create a new list with them in:
word1 = ['H', 'e', 'l', 'l', 'o']
word2 = ['w', 'o', 'r', 'l', 'd']
word1join = "".join(word1)
word2join = "".join(word2)
print([word1join, word2join])
Output as requested
If your variable names have numbers in them, it's usually a good hint that you should better be manipulating one list, rather than several individual variables.
Instead of starting with two variables:
word1 = ['H', 'e', 'l', 'l', 'o']
word2 = ['w', 'o', 'r', 'l', 'd']
Start with one list:
words = [['H', 'e', 'l', 'l', 'o'], ['w', 'o', 'r', 'l', 'd']]
You can still access individual words using indexing:
print(words[1])
# ['H', 'e', 'l', 'l', 'o']
You can then apply operations to every element of that list using for-loops, or list comprehensions, or function map:
words_joined = [''.join(word) for word in words]
# ['Hello', 'world']
# OR ALTERNATIVELY
words_joined = list(map(''.join, words))
# ['Hello', 'world']
If you really need to split the list into two variables, you can still do it:
word1joined, word2joined = words_joined
print(word2joined)
# world
For example:
content of myfile has
fsdfasf
frjfmcd
39djaxs
I want to convert this in to a matrix where it consists of
my_matrix=[['f','s','d','f','a','s','f'],['f','r','j'......]]
I've tried reading the file using
for line in file:
line = line.strip('\n)
print(line)
But it's not giving me the desired output.
What am I missing to do?
You need to turn your string into a list to get the output you want. Since strings are sequences, when you pass a string to list() if breaks it up into individual characters:
with open(path) as file:
matrix = [list(line.strip()) for line in file]
matrix:
[['f', 's', 'd', 'f', 'a', 's', 'f'],
['f', 'r', 'j', 'f', 'm', 'c', 'd'],
['3', '9', 'd', 'j', 'a', 'x', 's']]
correctAnswers = ['A','C','A','A','D','B','C','A','C','B','A','D','C','A','D','C','B','B','D','A']
studentAnswers = []
correctList = []
file = open('forchapter7.txt','r')
student = file.readline()
student = student.rstrip('\n')
studentAnswers.append(student)
while student != '':
student = file.readline()
student = student.rstrip('\n')
studentAnswers.append(student)
print(studentAnswers)
print(correctAnswers)
file.close()
#displays this
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', '']
['A', 'C', 'A', 'A', 'D', 'B', 'C', 'A', 'C', 'B', 'A', 'D', 'C', 'A', 'D', 'C', 'B', 'B', 'D', 'A']
my text file is a plain .txt file with the letters A-T going down and no space or new line after T, why is my loop writing the blank space?
When you read your final line, student == 'T', so the loop repeats itself. When you try to file.readline() after you have finished reading the entire file, it returns '' because there is nothing else to read. You are then adding this to your list.
Just add a check for empty string before adding to the list:
if student:
studentAnswers.append(student)
EDIT:
An alternative you could use is to read all the lines with file.readlines() and iterate over the list. This will not run the loop an extra time:
for student in file.readlines():
studentAnswers.append(student.rstrip('\n')
You can even use list comprehension this way:
studentAnswers = [student.rstrip('\n') for student in file.readlines()]
Note, however, that if the file does have an empty line these last two methods will need checks to prevent them from adding an empty entry to the list.