I have two lists:
list1=('a','b','c')
list2=('2','1','3')
and a text file
the text file has 3 lines so I want to add
'a' in the 2nd line
'-' in others,
'b' in the 1st line
'-' in others, and
'c' in the 3rd line
'-' in others according to the list1 and list2 like this
xxxx-b-
xxxxa--
xxxx--c
First task is to get the first list sorted correctly. This is easy if you zip the two lists together and then sort based on the (int-converted) line number:
>>> list1 = ['a', 'b', 'c']
>>> list2 = ['2', '1', '3']
>>> sorted(zip(list1, list2), key=lambda p: int(p[1]))
[('b', '1'), ('a', '2'), ('c', '3')]
Then you need to format the letter into the appropriate string. I'd do that with something like:
'xxxx' + ''.join(char if char == letter else '-' for char in 'abc')
so all together it's:
>>> for row in [
... 'xxxx' + ''.join(char if char == letter else '-' for char in 'abc')
... for letter, _line in sorted(zip(list1, list2), key=lambda p: int(p[1]))
... ]:
... print(row)
...
xxxx-b-
xxxxa--
xxxx--c
Now you just need to write it to the appropriate text file instead of printing it; since you don't specify how you want to do that (is it a specific text file? is it the parameter to a function? is it an existing file you're appending to?) I'll leave that part for you to fill in. :)
I did it but I think there is a good method than my
list1=['1','4','3','2']
list2=['a','b','c','d']
j=0
while j < len(list1):
with open("note2.txt",'r+') as f:
line = f.readlines()
note=""
f.seek(0)
for index,line in enumerate(line):
if index==list1[j]:
note+=line.strip()+ str(list2[j])+'\n'
else:
note+=line.strip()+ '-\n'
f.write(note)
f.close()
j+=1
Related
I'm working on a text pattern problem. I've the following input -
term = 'CG-14/0,2-L-0_2'
I need to remove all the possible punctuation (delimiters) from the input term. Basically I need the following output from the input term -
'CG1402L02'
I also need to store (in any format (object, dict, tuple etc.)) the delimiter and the position of the delimiter before removing the delimiters.
Example of the output (If returned as tuple) -
((-,2), (/,5), (,,7), (-,9), (-,11), (_,13))
I'm able to get the output using the following python code -
re.sub(r'[^\w]', '', term.replace('_', ''))
But how do I store the delimiter and delimiter position (in the most efficient way) before removing the delimiters?
You can simply walk once through term and collect all nessessary infos on the way:
from string import ascii_letters,digits
term = 'CG-14/0,2-L-0_2'
# defined set of allowed characters a-zA-Z0-9
# set lookup is O(1) - fast
ok = set(digits +ascii_letters)
specials = {}
clean = []
for i,c in enumerate(term):
if c in ok:
clean.append(c)
else:
specials.setdefault(c,[])
specials[c].append(i)
cleaned = ''.join(clean)
print(clean)
print(cleaned)
print(specials)
Output:
['C', 'G', '1', '4', '0', '2', 'L', '0', '2'] # list of characters in set ok
CG1402L02 # the ''.join()ed list
{'-': [2, 9, 11], '/': [5], ',': [7], '_': [13]} # dict of characters/positions not in ok
See:
string.ascii_letters
string.digits
You can use
specials = []
and inside the iteration:
else:
specials.append((c,i))
to get a list of tuples instead of the dictionary:
[('-', 2), ('/', 5), (',', 7), ('-', 9), ('-', 11), ('_', 13)]
You could do something like this, adding whatever other delimiters you need to the list delims
term = 'CG-14/0,2-L-0_2'
delims = ['-','/',',','_']
locations = []
pos = 0
for c in term: ##iterate through the characters in the string
if c in delims:
locations.append([c,pos]) ##store the character and its original position
pos+=1
And then do you re.sub command to replace them.
Code (incomplete):
list1 = ['1', '2', '3']
list2 = ['a', 'b', 'c']
list3 = ['12' '13' '14']
for list_in in list1:
with open("buffer_file") as f:
for line in f:
if len(line.split(" ")) >= 3:
var1 = line.split(" ")
if var1[0] == list1[0] and var[1] == list2[0] and var[3] == list3[0]:
buffer_file:
no
priority enabled
1 a 12
2 b 13
3 d 14
pump it
What I am trying here is if in file line and list values are matched then print file line is matched.
Example 1:
list1[0], list2[0], list3[0]
is matched with line contains 1 a 12 values so print matched
Example 2:
list1[1], list2[1], list3[1]
is matched with line contains 2 b 13 values so print matched
Example 3:
list1[2], list2[2], list3[2]
is not matched because line contains 3 d 12 values print not matched and also print not matched element that is d
Any one please suggest me what is the best way get this done. I am struck in middle of my code.
You can zip your three lists so that you can grab and check their values as triplets of aligned elements.
expected = zip(list1, list2, list3)
print expected
[ ('1', 'a', '12'), ('2', 'b', '13'), ... ]
If the lines in the file match your list elements one to one, you can then use zip() again to loop through the expected and actual values together. zip() is your friend. (If the file has extra lines, use a variable to walk down the list of triples.)
with open("buffer_file") as f:
for exp, actual in zip(expected, f):
if exp == actual.split(): # compares two 3-tuples
<etc.>
Reading between the lines a bit here. Essentially sounds line you want to ignore all the lines are't triples, enumerate over the file and find matches in your original list.
values = [
['1', '2', '3'],
['a', 'b', 'c'],
['12', '13', '14'],
]
def triples(line):
return len(line.split()) >= 3
with open("test_file.txt") as f:
content = filter(triples, (map(str.strip, f.readlines())))
# Loop over the file keeping track of index
for index, line in enumerate(content):
# Compare split line and triples
if line.split() == list(map(itemgetter(index), values)):
print(line)
Gives me, where "test_file.txt" contains your listed input
1 a 12
2 b 13
I need to read a file containing information on different lines - for example the file may contain
12345678910
abcdefghij
zyxwvutsrq
I will then need to read the code diagonally so my list would be:
(1bx)(2cw)(3dv)
I have tried using zip and just can't figure out a way to get it to work.
EDIT
Is there anyway to also make it take into account the diagonals before the top left corner for example:
(ay)(z)
in the example file I used.
Edit 2: this is my almost complete code
with open(FileName) as diagonal :
a = diagonal.read().splitlines()
l = [a[i][i:] for i in range(len(a))]
Diaglist = [''.join(i) for i in zip(*l)]
with open(FileName) as diagonal1 :
b = diagonal1.read().splitlines()
o = [b[i][:i] for i in range(len(b))]
Diaglist1 = [''.join(i) for i in zip(*o)]
When I run the file I get the correct diagonals for the first with so from the top right to left but the second with so from the top right downwards I just get an empty list.
Do you mean:
>>> with open('file') as f:
... l = f.read().splitlines()
>>> l
['12345678910', 'abcdefghij', 'zyxwvutsrq']
>>> l = [l[0]] + [l[1][1:]] + [l[2][2:]] # remove 'a' from `l[1]` and `zy` from `l[2]`
>>> l
['12345678910', 'bcdefghij', 'xwvutsrq']
>>> list(zip(*l)) # zip them
[('1', 'b', 'x'), ('2', 'c', 'w'), ('3', 'd', 'v'), ('4', 'e', 'u'), ('5', 'f', 't'), ('6', 'g', 's'), ('7', 'h', 'r'), ('8', 'i', 'q')]
>>> [''.join(i) for i in list(zip(*l))] # also join them
['1bx', '2cw', '3dv', '4eu', '5ft', '6gs', '7hr', '8iq']
>>>
If you don't know how many lines in your file, we can use some magic code like [a[i][i:] for i in range(len(a))].
Try:
with open('file') as f:
a = f.read().splitlines()
l = [a[i][i:] for i in range(len(a))]
final_list = [''.join(i) for i in zip(*l)]
print(final_list)
As your edit, you can change a[i][i:] to a[i][:i]. Very simple:
with open('file') as f:
a = f.read().splitlines()
l = [a[i][:i] for i in range(len(a))]
final_list = [''.join(i) for i in zip(*l)][1:] # since the first element in the list will be empty (`''`), remove it.
print(final_list)
The following will work for an arbitrary number of lines of the same length, and wraps the final diagonals. This may not be what you want.
def diagonals(lines):
size = len(lines[0])
positions = [[(i + x) % size for x in range(len(lines))]
for i in range(size)]
return ["".join([lines[i][p] for i, p in enumerate(posn)])
for posn in positions]
>>> print(diagonals(['1234567891', 'abcdefghij', 'zyxwvutsrq']))
['1bx', '2cw', '3dv', '4eu', '5ft', '6gs', '7hr', '8iq', '9jz', '1ay']
with open("text.txt", 'r') as file:
for line in file:
line = line.rstrip('\n' + '').split(':')
print(line)
I am having trouble trying to remove empty lists in the series of arrays that are being generated. I want to make every line an array in text.txt, so I would have the ability to accurately access each element individually, of each line.
The empty lists display themselves as [''] - as you can see by the fourth line, I've tried to explicitly strip them out. The empty elements were once filled with new line characters, these were successfully removed using .rstrip('\n').
Edit:
I have had a misconception with some terminology, the above is now updated. Essentially, I want to get rid of empty lists.
Since I can't see your exact line, its hard to give you a solution that matches your requirements perfectly, but if you want to get all the elements in a list that are not empty strings, then you can do this:
>>> l = ["ch", '', '', 'e', '', 'e', 'se']
>>> [var for var in l if var]
Out[4]: ['ch', 'e', 'e', 'se']
You may also use filter with None or bool:
>>> filter(None, l)
Out[5]: ['ch', 'e', 'e', 'se']
>>> filter(bool, l)
Out[6]: ['ch', 'e', 'e', 'se']
If you wish to get rid of lists with empty strings, then for your specific example you can do this:
with open("text.txt", 'r') as file:
for line in file:
line = line.rstrip('\n' + '').split(':')
# If line is just empty
if line != ['']:
print line
How to replace each element in a list with an element in the same position from another list? I thought something like this might work:
list1 = ['a', 'b', 'c', 'd']
list2 = ['a_replaced', 'b_replaced', 'c_replaced']
text = open(textfile, 'r')
n = 0
for line in text:
line = line[0:len(line)-1]
line.replace(col[n], outcol[n])
print line
n + 1
But it doesn't work. What am I doing wrong?
5 things:
You reference col and outcol which I assume are actually list1 and list2.
list1 and list2 are different sizes, this will crash
You're not checking the bounds on n, so if your text file is longer than 4 lines it will crash
The line n + 1 doesn't actually do anything, it should be n += 1
line.replace doesn't do an inline replace, it returns a new string.
So change it to line = line.replace(...).
I don't know what you're trying to accomplish. This program replaces a in line 1 with a_replaced, b in line 2 with b_replaced, c in line 3 with c_replaced, and d in line 4 with d_replaced.
replacements = [('a', 'a_replaced'), ('b', 'b_replaced'), ('c', 'c_replaced'), ('d', 'd_replaced')]
text = open(textfile, 'r')
n = 0
for line in text:
if n >= len(replacements):
break
print line[:-1].replace(replacements[n][0], replacements[n][1])
n += 1
However if your're trying to apply all replacements on each line, here's how:
replacements = [('a', 'a_replaced'), ('b', 'b_replaced'), ('c', 'c_replaced'), ('d', 'd_replaced')]
text = open(textfile, 'r')
for line in text:
line = line[:-1]
for oldtext, newtext in replacements:
line = line.replace(oldtext, newtext)
print line
Or a shorter version of the above program:
replacements = [('a', 'a_replaced'), ('b', 'b_replaced'), ('c', 'c_replaced'), ('d', 'd_replaced')]
text = open(textfile, 'r').read()
for oldtext, newtext in replacements:
text = text.replace(oldtext, newtext)
print text,
replace returns new string. You need line = line.replace(col[n], outcol[n]).
replace doesn't change the string, it returns a copy of the modified string.
line = line.replace(col[n], outcol[n])
I think this is what you are trying to achieve, although it is difficult to tell from the code that you have provided:
list1 = ['a', 'b', 'c', 'd']
list2 = ['a_replaced', 'b_replaced', 'c_replaced', 'd_replaced']
text = open(textfile, 'r')
for line in text:
for index, old in enumerate(list1):
line = line.replace(old, list2[index])
print line
text.close()
This should work. Comment to clarify