Writing alternate lists' elements - Python - python

I am trying to write alternating elements of multiple lists to a file using Python. I can write all of one list, and then all of another list, but am having difficulty doing it in an alternate order. My code looks like this:
foo = ['a', 'b', 'c']
bar = ['1', '2', '3']
fileout = open('zut.txt', 'w')
for i, el in foo, bar:
fileout.write('%s\t%s' % (i, el))
However this produces a ValueError when I try and run it. For clarification, I am trying to produce a file like this:
a 1
b 2
c 3
Can anyone help me to achieve this? Thanks!

>>> zip(foo,bar)
[('a', '1'), ('b', '2'), ('c', '3')]
You can then iterate over the list and access the elements of the tuple.
>>> for tpl in zip(foo, bar):
... print '%s\t%s' % tpl
...
a 1
b 2
c 3

You can use the following code:
foo = ['a', 'b', 'c']
bar = ['1', '2', '3']
with open('zut.txt', 'w') as fileout:
for x,y in zip(foo, bar):
fileout.write('%s\t%s\n' % (x,y)) # you missed here '\n'
Read more about 'zip' and use 'with open...' to be sure that file will be automatically closed

for letter, number in zip(foo, bar):
fileout.write('%s\t\%s' % (letter, number))

You can use the built-in zip function, to create that kind of 'corresponding' list, and then write it to file:
foo = ['a', 'b', 'c']
bar = ['1', '2', '3']
lst = zip(foo, bar)
with open('zut.txt', 'w') as f:
for pair in lst:
f.write( '{0}\t{1}'.format(pair[0], pair[1]) )

Related

Store Key Value Pairs as List Comprehension

I have this function:
datapoints = 3
abc = ['a','b','c', ... 'z']
character = abc[:datapoints]
for n in character:
values = int(askstring("Title", "Value: ")) # 1
dat1= character.pop(0) # a
dat2 = dat1 + "," + str(values) # a,1
d = dat2.split(",") # [a,1]
data = list((d, d)) # [['a', '1']]
print(data)
unfortunately, the data gets overridden after every loop and therefore I get this:
[['a', '1'],['a', '1']]
[['b', '2'],['b', '2']]
[['c', '3'],['c', '3']]
instead of this:
[['A', 1],['B', 2]],['C', 3]]
I have tried also list(zip(d, d)), but that doesn't help at all:
[('a', 'a'),('1', '1')]
[('b', 'b'),('2', '2')]
[('c', 'c'),('3', '3')]
Thank you for any help
Your loop is overriding the values of data and d every time, you want to put data = [] at the beginning of the loop and data.append(d) in the middle of the loop. Example:
data = []
for n in character:
d = ...
data.append(d)
Your loop is popping characters from character and looping over the list. You want to do either:
for n in character:
dat1 = n
Or:
while character:
dat1 = character.pop(0)

Print 2 lists side by side

I'm trying to output the values of 2 lists side by side using list comprehension. I have an example below that shows what I'm trying to accomplish. Is this possible?
code:
#example lists, the real lists will either have less or more values
a = ['a', 'b', 'c,']
b = ['1', '0', '0']
str = ('``` \n'
'results: \n\n'
'options votes \n'
#this line is the part I need help with: list comprehension for the 2 lists to output the values as shown below
'```')
print(str)
#what I want it to look like:
'''
results:
options votes
a 1
b 0
c 0
'''
You can use the zip() function to join lists together.
a = ['a', 'b', 'c']
b = ['1', '0', '0']
res = "\n".join("{} {}".format(x, y) for x, y in zip(a, b))
The zip() function will iterate tuples with the corresponding elements from each of the lists, which you can then format as Michael Butscher suggested in the comments.
Finally, just join() them together with newlines and you have the string you want.
print(res)
a 1
b 0
c 0
This works:
a = ['a', 'b', 'c']
b = ['1', '0', '0']
print("options votes")
for i in range(len(a)):
print(a[i] + '\t ' + b[i])
Outputs:
options votes
a 1
b 0
c 0
from __future__ import print_function # if using Python 2
a = ['a', 'b', 'c']
b = ['1', '0', '0']
print("""results:
options\tvotes""")
for x, y in zip(a, b):
print(x, y, sep='\t\t')
[print(x,y) for x,y in zip(list1, list2)]
Note the square brackets enclosing the print statement.

Comparing elements between two lists of lists in python

List A:
[('Harry', 'X', 'A'),
('James', 'Y', 'G'),
('John', 'Z', 'D')]
List B:
[('Helen', '2', '(A; B)', '3'),
('Victor', '9', '(C; D; E)', '4'),
('Alan', '10', '(A)', '57'),
('Paul', '11', '(F; B)', '43'),
('Sandra', '12', '(F)', '31')]
Basically I have to compare the third element (for x in listA -> x[2]) from list A and check if is there any list in list B that has the same element (for y in listB, x[2] == y[2]) but I'm just losing my mind with this.
My idea was to get the third element from each list in list B, put them into a new list, and then remove that ";" so I could access each element way more easily.
for x in listB:
j = x[2]
j = j.strip().split(', ')
for k in j:
FinalB.append(k)
FinalB = [(k[1:-1].split(";")) for k in FinalB]
Then I'd take the third element from each list of list A and compare them with the elements inside each list of FinalB: if there was a match, I'd get the index of the element in FinalB (the one that's matched), use that index to access his list in listB and get the first element of his list inside list B (basically, I have to know the names from the users inside each list that have the same 3rd element)
My code so far:
FinalB= []
DomainsList = []
for x in listA:
j = x[2]
j = j.strip().split(', ')
for k in j:
FinalB.append(k)
FinalB = [(k[1:-1].split(";")) for k in FinalB]
for y in listA:
for z in FinalB:
for k in z:
if y[2] == k:
m = FinalB.index(z)
DomainsList.append([listA[m][0],listB[m][0]])
return DomainsList
Yes, this is not working (no error, I probably just did this in an absolute wrong way) and I can't figure out what and where I'm doing wrong.
First, I think a better way to handle '(C; D; E)' is to change it to 'CDE', so the first loop becomes:
FinalB = [filter(str.isalpha, x[2]) for x in listB]
We take each string and keep only the alpha characters, so we end up with:
In [18]: FinalB
Out[18]: ['AB', 'CDE', 'A', 'FB', 'F']
This means we can use listA[x][2] in FinalB[y] to test if we have a match:
for y in listA:
for z in FinalB:
if y[2] in z:
DomainsList.append([y[0], listB[FinalB.index(z)][0]])
I had to tweak the arguments to the append() to pick the right elements, so we end up with:
In [17]: DomainsList
Out[17]: [['Harry', 'Helen'], ['Harry', 'Alan'], ['John', 'Victor']]
Usefully, if instead of '(C; D; E)' you have '(foo; bar; baz)', then with just one tweak the code can work for that too:
import re
FinalB = [filter(None, re.split("[; \(\)]+", x[2])) for x in listB]
The remaining code works as before.
It will always help to start a question with context and details.
The python version could also come into play.
The data structure you have given for us to work with is very questionable - especially the third element in each of the tuples in listB...why have a string element and then define it like this '(C; D; E)' ??
Even though I don't understand where you are coming from with this or what this is meant to achieve,no context provided in post, this code should get you there.
It will give you a list of tupples ( listC ), with each tuple having two elements. Element one having the name from listA and element 2 having the name from listB where they have a match as described in post.
NOTE: at the moment the match is simply done with a find, which will work perfectly with the provided details, however you may need to change this to be suitable for your needs if you could have data that would cause false positives or if you want to ignore case.
listA = [('Harry', 'X', 'A'), ('James', 'Y', 'G'), ('John', 'Z', 'D')]
listB = [('Helen', '2', '(A; B)', '3'),
('Victor', '9', '(C; D; E)', '4'),
('Alan', '10', '(A)', '57'),
('Paul', '11', '(F; B)', '43'),
('Sandra', '12', '(F)', '31')]
listC = []
for a in listA:
for b in listB:
if b[2].find(a[2]) != -1:
listC.append((a[0], b[0]))
print(listC)
This gives you.
[('Harry', 'Helen'), ('Harry', 'Alan'), ('John', 'Victor')]

Reading from a file diagonally and having the diagonal characters create a list

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']

Remove duplicate from two lists without using loop?

I have two list:
a=['1','2','3','3','3']
b=['a','b','c','d','e']
these two lists have the same amount of items. I want to delete duplicate in a and for b with same index. for this example, I would like to have the result as
a=['1','2','3']
b=['a','b','c']
I am not so familiar with Python, the only way I think is to use loop
for item in a
if find duplicate
delete b with same index
I want to ask, is there any better way to do this, other than using loop?
You can use a set for this:
>>> seen = set()
>>> new_a, new_b = [], []
>>> for x, y in zip(a, b):
... if x not in seen:
... new_a.append(x)
... new_b.append(y)
... seen.add(x)
...
>>> new_a
['1', '2', '3']
>>> new_b
['a', 'b', 'c']
Another way to do it using itertools.compress(Python 2.7+ and 3.1+ only):
>>> from itertools import compress, tee
>>> seen = set()
>>> f1, f2 = tee(True if x not in seen and not seen.add(x) else False for x in a)
>>> list(compress(a, f1))
['1', '2', '3']
>>> list(compress(b, f2))
['a', 'b', 'c']
You can use set for removing duplicate entries in a list. Please use following code to get desired output.
#!/usr/bin/python
a=['1','2','3','3','3']
b=['a','b','c','d','e']
a=set(a)
print list(a)
lena=len(a)
b=set(b)
b=list(b)
print b[:lena]
output:
>>>
['1', '3', '2']
['a', 'c', 'b']

Categories

Resources