I have a list like this:
list_input = [(a,b), (a,c), (a,d), (z,b), (z,e)]
I want to extract b, c and d when start it with "a" not with "z" and put in a list
I could not figure out how to do it, any advice?
Filter your list items on the first value, collecting the second:
[second for first, second in list_input if first == 'a']
Demo:
>>> list_input = [('a', 'b'), ('a', 'c'), ('a', 'd'), ('z', 'b'), ('z', 'e')]
>>> [second for first, second in list_input if first == 'a']
['b', 'c', 'd']
You could also do it explicitly:
In [8]: [list_input[i][1] for i in xrange(len(list_input)) if list_input[i][0] =='a']
Out[8]: ['b', 'c', 'd']
Or;
list_input = [("a","b"), ("a","c"), ("a","d"), ("z","b"), ("z","e")]
print ([x[1] for x in list_input if x[0]=="a"])
>>>
['b', 'c', 'd']
>>>
Manipulate it with indices. You can display that specific pairs too;
print ([(x,x[1]) for x in list_input if x[0]=="a"])
output;
>>>
[(('a', 'b'), 'b'), (('a', 'c'), 'c'), (('a', 'd'), 'd')]
>>>
Related
My goal is to create 3 lists.
The 1st one is the input: choose 3 from ABCD to create AAA, ABC...etc
The 2nd one is the output: change the middle letter of each input and create a new list. eg: for AAA -> ABA,ACA,ADA. So 3 times the length of the input.
The third one is the Change: I want to name each change as c_i, for example, AAA->ABA is C1.
For Input,
>>> lis = ["A","B","C","D"]
>>> import itertools as it
>>> inp = list(it.product(lis, repeat = 3))
>>> print(inp)
[('A', 'A', 'A'), ('A', 'A', 'B'), ... ('D', 'D', 'C'), ('D', 'D', 'D')]
>>> len(inp)
64
But I am stuck on how to create the output list. Any idea is appreciated!
Thanks
You can use list comprehension:
import itertools
lst = ['A', 'B', 'C', 'D']
lst_input = list(itertools.product(lst, repeat=3))
lst_output = [(tup[0], x, tup[2]) for tup in lst_input for x in lst if tup[1] is not x]
lst_change = [f'C{i}' for i in range(1, len(lst_output) + 1)]
print(len(lst_input), len(lst_output), len(lst_change))
print(lst_input[:5])
print(lst_output[:5])
print(lst_change[:5])
# 64 192 192
# [('A', 'A', 'A'), ('A', 'A', 'B'), ('A', 'A', 'C'), ('A', 'A', 'D'), ('A', 'B', 'A')]
# [('A', 'B', 'A'), ('A', 'C', 'A'), ('A', 'D', 'A'), ('A', 'B', 'B'), ('A', 'C', 'B')]
# ['C1', 'C2', 'C3', 'C4', 'C5']
For each tuple in lst_input, the middle item is replaced by all the candidate characters, but the replacement is thrown out if that replacement character is the same as the original character (if tup[1] is not x).
I have this array:
lst = ['A', 'B', 'C']
How could I append a string 'D' to each element and convert every set as a tuple:
lst2= [('A', 'D'),
('B', 'D'),
('C', 'D')]
Like this, using a list comprehension:
lst = ['A', 'B', 'C']
lst2 = [(x, 'D') for x in lst]
lst2
=> [('A', 'D'), ('B', 'D'), ('C', 'D')]
By the way, it's a bad idea to call a variable list, that clashes with a built-in function. I renamed it.
alternative solution is use zip_longest
from itertools import zip_longest
list(zip_longest(['A', 'B', 'C'], [], fillvalue='D'))
the result wiil be:
[('A', 'D'), ('B', 'D'), ('C', 'D')]
list2 = [(i, 'D') for i in list]
(apart from the fact that list is a very bad variable name)
Another option using zip:
x = ['A', 'B', 'C']
res = list(zip(x,'D'*len(x)))
list1 = ['A', 'B', 'C']
list2 = []
for i in list1:
list2.append((i, 'D'))
print(list2)
You can use the function product():
from itertools import product
lst = ['A', 'B', 'C']
list(product(lst, 'D'))
# [('A', 'D'), ('B', 'D'), ('C', 'D')]
For example, I have a list like ('A', 'B', 'C', 'D', ('A', 'B'), ('A', 'C'), ('C', 'D'))
In this list, I want to take elements that form () with 'A' elements.
This means, I want to take elements ('A', 'B') and ('A', 'C')
Not 'A', 'B' or ('C', 'D')
How can I get this?
l = ('A', 'B', 'C', 'D', ('A', 'B'), ('A', 'C'), ('C', 'D'))
[x for x in l if type(x) == tuple and 'A' in x]
I would use a conditional list comprehension. I check if 'A' is in the list and if it is and the content isn't only A (hence the len check), then add it to the list.
temp = ('A', 'B', 'C', 'D', ('A', 'B'), ('A', 'C'), ('C', 'D'))
results = [i for i in temp if 'A' in i and len(i) > 1]
print(results)
You can loop through like this:
new_lst = []
lst = ('A', 'B', 'C', 'D', ('A', 'B'), ('A', 'C'), ('C', 'D'))
for i in lst:
if len(i) > 1 and i[0] == "A":
new_lst.append(i)
print new_lst
My function is currently returning:
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
However, I need the final output to be:
[('a', 'h'), ('d', 'g')]
As you can see, if i[1] and i[2] match I need i[0] to be paired together.
I was trying to use a for loop but I can't think of how to write it, at this moment.
This seems to work:
from itertools import combinations
l = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
print([(a[0], b[0]) for a, b in combinations(l, 2) if a[1:] == b[1:]])
You can do this by sorting the list based on second and third element , and then using itertools.groupby . Then for each group, you can take the first elements from the elements inside it. Example -
>>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
>>> lst = []
>>> new_a = sorted(a, key=lambda i: (i[1], i[2]))
>>> for _, x in itertools.groupby(new_a, lambda i: (i[1], i[2])):
... lst.append(tuple(y[0] for y in x))
...
>>> lst
[('a', 'h'), ('d', 'g')]
This can also be done in one line as (though unreadable) -
>>> l = [tuple(y[0] for y in x) for _, x in itertools.groupby(sorted(a, key=lambda i: (i[1], i[2])), lambda i: (i[1], i[2]))]
>>> l
[('a', 'h'), ('d', 'g')]
group based on the second and third elements of each tuple, appending the first element to a list then filter out the lists that have a length < 1:
from collections import defaultdict
d = defaultdict(list)
for a,b,c in l:
d[b,c].append(a)
print([tuple(val) for val in d.values() if len(val)>1])
[('a', 'h'), ('d', 'g')]
To guarantee first match order use an OrderedDict:
from collections import OrderedDict
d = OrderedDict()
for a,b,c in l:
d.setdefault((b,c),[]).append(a)
print([tuple(val) for val in d.values() if len(val)>1])
I think this solution will preserve order (based on initial match location):
from itertools import groupby
from operator import itemgetter
from collections import defaultdict
x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
groupings, seen_list=defaultdict(list), []
for key, value in groupby(x, itemgetter(1, 2)):
if key not in seen_list:
seen_list.append(key)
groupings[key].extend(list(map(itemgetter(0),value)))
print([groupings[key] for key in seen_list])
if order is not important you can disregard the seen_list and just print the groupings.values()
x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
groupings=defaultdict(list)
for key, value in groupby(x, itemgetter(1, 2)):
groupings[key].extend(list(map(itemgetter(0),value)))
print(groupings.values())
May be not so pythonic, but a bit easier:
>>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
>>> c = {}
>>> [c[j+k].append(i) if j+k in c else c.update({j+k:[i]}) for i,j,k in a]
>>> c = c.values()
>>> print c
[['d', 'g'], ['a', 'h']]
How to turn multiple lists into one list of sublists, where each sublist is made up of the items at the same index across the original lists?
lsta = ['a','b','c','d']
lstb = ['a','b','c','d']
lstc = ['a','b','c','d']
Desired_List = [['a','a','a'],['b','b','b'],['c','c','c'],['d','d','d']]
I can't seem to use zip here, so how would I do this?
List of list will give like this:
>>> [list(x) for x in zip(lsta, lstb, lstc)]
[['a', 'a', 'a'], ['b', 'b', 'b'], ['c', 'c', 'c'], ['d', 'd', 'd']]
>>>
Using zip, under duress:
>>> zip(lsta, lstb, lstc)
[('a', 'a', 'a'), ('b', 'b', 'b'), ('c', 'c', 'c'), ('d', 'd', 'd')]
If Python 3, you'll need to convert the zip to a list:
>>> list(zip(lsta, lstb, lstc))
[('a', 'a', 'a'), ('b', 'b', 'b'), ('c', 'c', 'c'), ('d', 'd', 'd')]