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.
Related
This question already has answers here:
Python Variable assignment in a for loop
(6 answers)
Closed 1 year ago.
I am trying to split strings within nested lists, but for whatever reason, the strings do not split as I expect them to. For example, here is a nested list where I have strings that I want to split.
myList=[['letters', ['a b c d e', 'f g h i j']], ['digits', ['0 1 2 3 4', '5 6 7 8 9']]]
I have tried using for loops to split each string, but it doesn't seem to work. I tried using the following code:
for i in myList:
for j in i[1]:
j=j.split()
However, it seems to do nothing to the list. I expect that after running the code, myList should contain
[['letters', [['a', 'b', 'c', 'd', 'e'], ['f', 'g', 'h', 'i', 'j']]], ['digits', [['0', '1', '2', '3', '4'], ['5', '6', '7', '8', '9']]]]
If I look at each item using print() and repr(), I see the strings that I expect.
for i in myList2:
for j in i[1]:
print(repr(j))
prints out
'a b c d e'
'f g h i j'
'0 1 2 3 4'
'5 6 7 8 9'
as I expect, so I am unsure why the split values cannot be written.
The syntax j = j.split() doesn't modify the object referenced by j, it just reference j to a NEW thing : the splitted list, and that have no impact on the main list, you need to create a new one
myList = [[i[0], [j.split() for j in i[1]]] for i in myList]
Heavier, but maybe more understandable syntax
result = []
for i in myList:
tmp_list = []
for j in i[1]:
tmp_list.append(j.split())
result.append([i[0], tmp_list])
print(result)
You should specify the location in the nested list to overwrite. Modifying your code as follows:
for idx, i in enumerate(myList):
for ix, j in enumerate(i[1]):
# j = j.split()
myList[idx][1][ix] = j.split()
print(myList)
results in required output.
I am currently trying to obtain top 2 maximum values from the following list (Quant) and its corresponding value from the 2nd list (FF).
Quant = ['1', '29', '109', '2', '1', '1', '100']
FF = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
The top 2 max value in 1st list is 100 & 109 and its corresponding value in 2nd list is c & g. I tried to get the position of top values in Quant list by the following method.
a = max(Quant)
pos1 = [i for i, j in enumerate(Qu) if j == a]
Quant.remove(a)
b = max(Quant)
pos2 = [i for i, j in enumerate(Qu) if j == b]
for x, y in zip(pos1, pos2)
FC1 = FF[x]
FC2 = FF[y]
i am not sure if it is the correct way. The current Quant list does not contain duplication in max values. What if there are duplication and in that case pos1 will have 2 index values. If yes, In that i would need those 2 values from list 1 along with the subsequent value from list2.
Kindly assist me on the part.
In one line, you can do this by sorting the zipped list then unzipping only the first two items:
((FC1,FC2), (pos1,pos2)) = zip(
*sorted(zip(Quant,FF), key=lambda x:int(x[0]), reverse=True)[:2])
or if you interchange the variables, you don't even need to unzip:
((FC1,pos1), (FC2,pos2)) = sorted(zip(Quant,FF),
key=lambda x:int(x[0]), reverse=True)[:2]
>>> FC1
'109'
>>> FC2
'100'
>>> pos1
'c'
>>> pos2
'g'
This would do it, I hope you find it an elegant solution:
[*map(lambda x: FF[x], map(lambda x: Quant.index(str(x)), sorted(map(int, Quant),
reverse=True)[:2]))]
['c', 'g']
Or this:
[FF[i] for i in map(lambda x: Quant.index(str(x)), sorted(map(int, Quant),
reverse=True)[:2])]
Will the values in Quant always be strings? If you have control over it, you should make them numbers, because right now max(Quant) returns 29.
Here's one way to get what you're looking for:
Quant = ['1', '29', '109', '2', '1', '1', '100']
FF = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
quantNums = [int(n) for n in Quant]
max2, max1 = sorted(zip(quantNums, FF))[-2:]
max1 # (109, 'c')
max2 # (100, 'g')
You can achieve that using numpy,
import numpy as np
# Convert the list to numpy array
Quant = ['1', '29', '109', '2', '1', '1', '100']
Quant = np.array(Quant).astype(int)
# Get the two largest elements
ind = Quant.argsort()[-2:]
# Get the values from FF
FF = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
FF[ind]
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)
I am trying to learn greedy string tiling in algorithm
I have two lists as follows:
a=['a','b','c','d','e','f']
b=['d','e','a','b','c','f']
i would like to retrieve c=['a','b','c','d','e']
Another example would be
a = ['1','2','3','4','5','6','7','8','9','1','3']
b = ['3','4','5','2','1','7','8','9','1']
c should be ['3','4','5','7','8','9','1']
Right now I am using the following code which works for the latter example but not the former. Can someone help?
def gct(a, b):
if len(a) == 0 or len(b) == 0:
return []
if a[0] == b[0]:
return [a[0]] + gct(a[1:], b[1:])
return max(gct(a, b[1:]), gct(a[1:], b), key=len)
I am calling function with
gct( ['a','b','c','d','e','f'], ['d','e','a','b','c','f'] )
which gives ['a', 'b', 'c', 'f'], when it should be ['a','b','c','d','e'] or ['d','e','a','b','c'].
P.S The order doesn't matter in the printing of the result. The order is only important while doing the comparisons. The minimum pattern length should be 2
NOTE intersect will not solve my problem
The following codes can solve the problem. A minlength is added to make sure the substr >= minlength.
maxsub is used to find the longest substr and return its index in string a.
markit.a is used to mark the char position found before in string a.
while loop is used to find all the substr (len>=minlength)
^
#! /usr/bin/env python
a=['a','b','c','d','e','f']
b=['d','e','a','b','c','f']
a = ['1','2','3','4','5','6','7','8','9','1','3']
b = ['3','4','5','2','1','7','8','9','1']
def gct(a,b,minlength=2):
if len(a) == 0 or len(b) == 0:
return []
# if py>3.0, nonlocal is better
class markit:
a=[0]
minlen=2
markit.a=[0]*len(a)
markit.minlen=minlength
#output char index
out=[]
# To find the max length substr (index)
# apos is the position of a[0] in origin string
def maxsub(a,b,apos=0,lennow=0):
if (len(a) == 0 or len(b) == 0):
return []
if (a[0]==b[0] and markit.a[apos]!=1 ):
return [apos]+maxsub(a[1:],b[1:],apos+1,lennow=lennow+1)
elif (a[0]!=b[0] and lennow>0):
return []
return max(maxsub(a, b[1:],apos), maxsub(a[1:], b,apos+1), key=len)
while True:
findmax=maxsub(a,b,0,0)
if (len(findmax)<markit.minlen):
break
else:
for i in findmax:
markit.a[i]=1
out+=findmax
return [ a[i] for i in out]
print gct(a,b)
>> ['a', 'b', 'c', 'd', 'e']
>> ['7', '8', '9', '1', '3', '4', '5']
print gct(a,b,3)
>> ['a', 'b', 'c']
>> ['7', '8', '9', '1', '3', '4', '5']
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']