List comprehension python and specific item - python

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

Attempting to build a loop to change one str out of 3 strs in python

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).

Create tuples from a list in Python

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

I need your help about a list

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

How to create a new list of tuples based on a values from original list of tuples?

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 a list of sublists where each sublist is made up of the same index items across all lists?

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

Categories

Resources