I have a nested list like this.
[['a','g','c'],['e','c','g']...]
I am trying to see if third entry is equal to second entry in the list. If it is, I want to return first entry in that list. So since 3rd entry in list 1 is c, I want to look for c in second entry in all the list. Since list 2 has corresponding value in 2nd entry, I want to return e, then append that to nested list 1. There are multiple lists,and want to do it for all the list.
So
[['a','g','c','e']...]]
You could try the below,
>>> l = [['a','g','c'],['e','c','g']]
>>> i = l[0][2] # stores the value of 2nd index of l[0] to the variable i
>>> m = l[0] # assigns the 0th index of l to m
>>> for j in l[1:]:
if i == j[1]:
m.append(j[0])
>>> m
['a', 'g', 'c', 'e']
A complex example.
>>> l = [['a','g','c'],['e','c','g'], ['m','c','g'], ['j','c','g'], ['k','f','g'], ['p','c','g']]
>>> i = l[0][2]
>>> m = l[0]
>>> for j in l[1:]:
if i == j[1]:
m.append(j[0])
>>> m
['a', 'g', 'c', 'e', 'm', 'j', 'p']
k=[['a','g','c'],['e','c','g'],['m','c','g'],['j','c','g'],['k','f','g'],['p','g','k']]
print [x+y[:1] for x,y in zip(k,k[1:]) if x[2]==y[1]]
Try this.
Related
Looking for combinations for n elements from list of lists but choosing only one element from each list. E.g.
list = [[a, b], [c,d], [e,f,g,h,i], [j,k,l,m, n], [o,p]..]
While choosing no more than one element from each list, I am trying to come up with different combinations
e.g: for combination of n = 2 elements:
[a,c] [b,c], [c,j]...so on
for combination of n = 3 elements:
[a,c,e], [a,d,f]..so on
for combination of n = 4 elements:
[a, c, j, o], [a,c, i, p] ...
I tried using itertools combinations, but quickly running into issues. Any hints?
Is this what you are trying to achieve?
import itertools
from pprint import pprint
original_lst = [['a', 'b'], ['c','d'], ['e','f','g','h','i'], ['j','k','l','m','n'], ['o','p']]
def two_on_same_sublist(items, lst):
for sub in lst:
for i in itertools.combinations(items, 2):
if all(x in sub for x in i):
return True
else:
continue
def possible_combinations_of_items_in_sub_lists_no_rep(lst, n):
flat_lst = [i for sublist in lst for i in sublist] # Make it one flat list
return [i for i in itertools.combinations(flat_lst, n) if not two_on_same_sublist(i, lst)]
pprint(possible_combinations_of_items_in_sub_lists_no_rep(original_lst, 3))
I think you are looking for something like this.
Find the min and max size of sub list. Then create a dictionary with keys ranging from min to max.
Code:
from collections import defaultdict
c = defaultdict(list)
lst = [['a','b'],
['c','d'],
['e','f','g','h','i'],
['j','k','l','m','n'],
['o','p'],
['q','r','s'],
['t','u','v'],
['w','x','y','z']]
a = min(map(len,lst)) #find min of sub list - here it will be 2
b = max(map(len,lst)) #find max of sub list - here it will be 5
for v in lst: #iterate thru the full list
c[len(v)].append(v) #store values into a dictionary with key = len (sublist)
c = dict(c) #convert it back to normal dict
#iterate from min thru max and print the combinations
#skip if key not found in dictionary
for i in range (a, b+1):
if i in c: print ('Combinations of n =',i, 'elements are :', c[i])
Output:
Combinations of n = 2 elements are : [['a', 'b'], ['c', 'd'], ['o', 'p']]
Combinations of n = 3 elements are : [['q', 'r', 's'], ['t', 'u', 'v']]
Combinations of n = 4 elements are : [['w', 'x', 'y', 'z']]
Combinations of n = 5 elements are : [['e', 'f', 'g', 'h', 'i'], ['j', 'k', 'l', 'm', 'n']]
I have a list containing strings and lists. Something like:
l = ['a', 'b', ['c', 'd'], 'e']
I need to find the index of an element I'm looking for in this nested list. For instance, if I need to find c, the function should return 2, and if I'm looking for d, it should return 2 too. Consider that I have to do this for a large number of elements. Before I was simply using
idx = list.index(element)
but this does not work anymore, because of the nested lists. I cannot simply flatten the list, as I then shall use the index in another list with the same shape as this one.
Any suggestion?
This is one approach, Iterating the list.
Ex:
l = ['a', 'b', ['c', 'd'], 'e']
toFind = "c"
toFind1 = "d"
for i, v in enumerate(l):
if isinstance(v, list):
if toFind1 in v:
print(i)
else:
if toFind1 == v:
print(i)
I want to combine two elements in a list based on a given condition.
For example if I encounter the character 'a' in a list, I would like to combine it with the next element. The list:
['a', 'b', 'c', 'a', 'd']
becomes
['ab', 'c', 'ad']
Is there any quick way to do this?
One solution I have thought of is to create a new empty list and iterate through the first list. As we encounter the element 'a' in list 1, we join list1[index of a] and list1[index of a + 1] and append the result to list 2. However I wanted to know if there is any way to do it without creating a new list and copying values into it.
This does not create a new list, just modifies the existing one.
l = ['a', 'b', 'c', 'a', 'd']
for i in range(len(l)-2, -1, -1):
if l[i] == 'a':
l[i] = l[i] + l.pop(i+1)
print(l)
If you don't want to use list comprehension to create a new list (maybe because your input list is huge) you could modify the list in-place:
i=0
while i < len(l):
if l[i]=='a':
l[i] += l.pop(i+1)
i += 1
Use a list comprehension with an iterator on your list. When the current iteratee is a simply join it with the next item from the iterator using next:
l = ['a', 'b', 'c', 'a', 'd']
it = iter(l)
l[:] = [i+next(it) if i == 'a' else i for i in it]
print l
# ['ab', 'c', 'ad']
Well, if you don't want to create a new list so much, here we go:
from itertools import islice
a = list("abcdabdbac")
i = 0
for x, y in zip(a, islice(a, 1, None)):
if x == 'a':
a[i] = x + y
i += 1
elif y != 'a':
a[i] = y
i += 1
try:
del a[i:]
except:
pass
you could use itertools.groupby and group by:
letter follows a or
letter is not a
using enumerate to generate the current index, which allows to fetch the previous element from the list (creating a new list but one-liner)
import itertools
l = ['a', 'b', 'c', 'a', 'd']
print(["".join(x[1] for x in v) for _,v in itertools.groupby(enumerate(l),key=lambda t: (t[0] > 0 and l[t[0]-1]=='a') or t[1]=='a')])
result:
['ab', 'c', 'ad']
This is easy way. Mb not pythonic way.
l1 = ['a', 'b', 'c', 'a', 'd']
do_combine = False
combine_element = None
for el in l1:
if do_combine:
indx = l1.index(el)
l1[indx] = combine_element + el
do_combine = False
l1.remove(combine_element)
if el == 'a':
combine_element = el
do_combine = True
print(l1)
# ['ab', 'c', 'ad']
Suppose list1 is [a, y, k, x, d, l]
How do I make a new list containing the first two and last two alphabetically (a, d, and x, y)?
You can use sorted to sort the original list, then use list slicing to get the first two and last two elements of the sorted list.
>>> list1 = ['a', 'y', 'k', 'x', 'd', 'l']
>>> sorted_list = sorted(list1)
>>> new_list = sorted_list[0:2] + sorted_list[-2:]
>>> new_list
['a', 'd', 'x', 'y']
I have two lists (of different lengths). One changes throughout the program (list1), the other (longer) doesn't (list2). Basically I have a function that is supposed to compare the elements in both lists, and if an element in list1 is in list2, that element in a copy of list2 is changed to 'A', and all other elements in the copy are changed to 'B'. I can get it to work when there is only one element in list1. But for some reason if the list is longer, all the elements in list2 turn to B....
def newList(list1,list2):
newList= list2[:]
for i in range(len(list2)):
for element in list1:
if element==newList[i]:
newList[i]='A'
else:
newList[i]='B'
return newList
Try this:
newlist = ['A' if x in list1 else 'B' for x in list2]
Works for the following example, I hope I understood you correctly? If a value in B exists in A, insert 'A' otherwise insert 'B' into a new list?
>>> a = [1,2,3,4,5]
>>> b = [1,3,4,6]
>>> ['A' if x in a else 'B' for x in b]
['A', 'A', 'A', 'B']
It could be because instead of
newList: list2[:]
you should have
newList = list2[:]
Personally, I prefer the following syntax, which I find to be more explicit:
import copy
newList = copy.copy(list2) # or copy.deepcopy
Now, I'd imagine part of the problem here is also that you use the same name, newList, for both your function and a local variable. That's not so good.
def newList(changing_list, static_list):
temporary_list = static_list[:]
for index, content in enumerate(temporary_list):
if content in changing_list:
temporary_list[index] = 'A'
else:
temporary_list[index] = 'B'
return temporary_list
Note here that you have not made it clear what to do when there are multiple entries in list1 and list2 that match. My code marks all of the matching ones 'A'. Example:
>>> a = [1, 2, 3]
>>> b = [3,4,7,2,6,8,9,1]
>>> newList(a,b)
['A', 'B', 'B', 'A', 'B', 'B', 'B', 'A']
I think this is what you want to do and can put newLis = list2[:] instead of the below but prefer to use list in these cases:
def newList1(list1,list2):
newLis = list(list2)
for i in range(len(list2)):
if newLis[i] in list1:
newLis[i]='A'
else: newLis[i]='B'
return newLis
The answer when passed
newList1(range(5),range(10))
is:
['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B']