I have a list of strings like the following:
L = ['aa','bb','cc']
I would like to apply an if condition on its elements to check if multiple strings are in it, and then keep only one element as result. The pseudo-code I'm trying to implement is:
if 'aa' in L AND 'cc' in L:
return the third element (i.e. 'bb')
else:
return 'aa'
So far I've been working with a list comprehension like:
return = ['aa' if elem != 'aa' and elem != 'cc' else elem for elem in L][0]
But it doesn't work as expected.
EDIT:
Fixed return as element and not a list.
I don't think you can do this with a single list comprehension. How about:
L = ['aa','bb','cc']
if "aa" in L and "cc" in L:
result = [item for item in L if item != "aa" and item != "cc"][0]
else:
result = "aa"
return result
Or return [item for item in L if item != "aa" and item != "cc"][0] if "aa" in L and "cc" in L else "aa" if you insist on doing it in one line.
You could find the difference between your lists using sets:
l = ['aa','bb','cc']
k = ['aa','cc']
if len(list(set(l) - set(k))) == 1:
return list(set(l) - set(k))
else:
return l[0]
If they return exactly one element return that, otherwise the first element of l.
Related
['16:False,', '15:False,', '17:True,']
I need to know the index of str with true value
It is at index 2 but how do i make code like this for that
Not sure if this is what you're asking for, but this will return the index of all items in the list with "True" in them:
my_list = ['16:False,', '15:False,', '17:True,']
indexes = [idx for idx, s in enumerate(my_list) if "True" in s]
print(indexes)
>>> [2]
Try next():
lst = ["16:False,", "15:False,", "17:True,"]
i = next((i for i, s in enumerate(lst) if "True" in s), None)
print(i)
Prints:
2
If "True" isn't found, i is set to None
You can use a list comprehension and the in command as such,
my_list = ['16:False,', '15:False,', '17:True,']
idx = [i for i, ele in enumerate(my_list) if "True" in ele]
print(idx)
The comprehension clocks through your list & takes note of the indices where the element, ele contains the string "True".
If there is more than one entry then you will get a list of indices, if there are no entries then you will get an empty list.
Another possible solution:
import numpy as np
l = ['16:False,', '15:False,', '17:True,']
np.where(['True' in x for x in l])[0]
#> array([2])
You can do it like this:
def find_true_index(lst):
for index, elem in enumerate(lst):
if 'True' in elem:
return index
return None
l = ['16:False,', '15:False,', '17:True,']
print(find_true_index(l))
It will return the index if it found it and None if it didn't. Although be careful as this will always only find the first occurance, it might be useful to add all the wanted indexes to the list and then return the list.
def get_true_index_list(data: list, only_first=False):
trues_list = []
for i, v in enumerate(data):
if 'True' in v:
true_index = int(v.split(':')[0])
if only_first:
return (i, true_index)
trues_list.append((i, true_index)
return trues_list
r1 = get_true_index_list(['16:True,', '15:False,', '17:True,'])
r2 = get_true_index_list(['16:False,', '15:False,', '17:True,'], only_first=True)
print(r1)
print(r2)
Result :
([(0,16),(2,17)])
(2,17)
Here, first value of tuple is lists's index and second value is int value in "True"
If you don't want the answer in a list.
given_list = ['16:False,', '15:False,', '17:True']
for i in range(0, len(given_list)):
if "True" in given_list[i]:
print i
Let's say I have the following list of lists:
final_list = [[1,'pppizza',3,4],[1,'mmmonkey',9,10],[1,'dddoublerainbow',8,2]]
Now I need to remove the first 2 characters of the second element of every list, so the result will be:
final_list = [[1,'pizza',3,4],[1,'monkey',9,10],[1,'doublerainbow',8,2]]
No need to rebuild the entire list from scratch just to do it in a one-line comprehension while unnecessarily iterating the inner lists. Just modify the elements that need modifying:
for lst in final_list:
lst[1] = lst[1][2:]
use double list comprehensions:
final_list = [[x if hasattr(x, '__len__') and i == 1 else x[2:] for i, x in enumerate(y)] for y in my_list]
this will trim the first 2 elements of the second element, even if the element is not a string
If you want it for strings only then the statement becomes:
final_list = [[x if type(x) == str and i == 1 else x[2:] for i, x in enumerate(y)] for y in my_list]
final_list = [[x[2:] if i==1 else x for i, x in enumerate(y)] for y in my_list]
Full answer:
final_list = []
for y in my_list:
l = []
for i, x in enumerate(my_list):
if i==1: #2nd element in the list
l.append(x[2:]) # Append a string starting from the 3rd letter to the end
else:
l.append(x) . # Just append the element at x
my_list.append(l) # Append the list l to my_list
print(my_list)
I am using lists to store attributes and this problem cropped up when I was searching for equal items:
l = [['a',1,2],['b',1,2],['c',2,3],['d',1,2]]
if [any,1,2] in l:
print ('blue')
elif [any,2,3] in l:
print('red')
desired output
blue
What I want is the first value being ignored/can be any value.
I know the any function doesn't work this way but what is the correct method to doing so?
Perhaps this is more understandable
l = [['a',1,2],['b',1,2],['c',2,3],['d',1,2]]
for a in range(0,4):
if [1,2] == x[1:] for x in l:
print ('blue')
elif [2,3] == x[1:] for x in l:
print('red')
For filtering equal items (according to your definition) you can use list comprehension and slicing:
>>> lst = [['a',1,2],['b',1,2],['c',2,3],['d',1,2]]
>>> [e for e in lst if e[1:] == [1,2]]
[['a', 1, 2], ['b', 1, 2], ['d', 1, 2]]
:D actually managed to do it in one line thanks to pkacprzak.
l = [['a',1,2],['b',1,2],['c',2,3],['d',1,2]]
if any(True for x in l if x[1:] == [1,2]):
print ('blue')
elif any(True for x in l if x[1:] == [2,3]):
print('red')
Code works like this:
True for x in l
iterates over l (<---this is the letter L btw) and returns True if the next bit is True
if x[1:] == [1,2]
this checks all values of x except the first and returns True
any(...)
finds if any of the values returned from the bit inside the any is True
You could also return the value of the first item like so
[x[0] for x in l if x[1:] == [1,2]]
and iterate over that as well
for completely generic case simply introduce some magical symbol to denote 'any' like '*' and write your own simple comparator
def matches(element, mask):
for el, mask_el in zip(element, mask):
if mask_el != '*' and el != mask_el:
return False
return True
and now you can do
for list_el in list:
if matches(list_el, ['*', 1, 2]):
print 'blah'
the nice thing is that it is very generic, and will work with arbitrary number of '*' in your mask.
I am new to python and I'm wondering, how I would go about removing items from a list. Say I have the list:
a=[(102,12,0),(123,12,0),(124,12,1)]
I would like to remove the items that have a 0 at the end, so my list would end up like:
a = [(124,12,1)]
here:
a = [i for i in a if i[-1] != 0] #list comprehension (1 line) method.
"normal" way to do without list comprehension when the parent list is also destination list.
tmp = []
for i in a:
if i[-1] != 0:
tmp.append(i)
a = tmp
in action:
>>> a=[(102,12,0),(123,12,0),(124,12,1)]
>>> a = [i for i in a if i[-1] != 0]
>>> a
[(124, 12, 1)]
>>>
You can use list comprehensions
val[-1] would give you tuples with 0 at the end, assuming val is the variable used while iterating.
So, your code would be something like this:
a = [val for val in a if val[-1]]
Not as awesome as a one liner list comprehension but still do the trick :).
b = tuple
for tple in a:
b = b + tple
result = tuple
for val in set(b):
if val % 10 != 0:
result = result + (val,)
I have a list which looks something like this:
mylist = ([(0.1, 0.5),(0.4, 1.0)], [(0.2, 0.4),(0.15, 0.6)], None, [(0.35, 0.8),(0.05, 1.0)])
What I would like to know is how do I check for the empty entry or None in the list and if there is one then it should continue further ignoring it. Something like,
if mylist == something :
do this
if mylist == [] or () or None :
ignore and continue
I am not able to put that into a code. Thank you.
Basically, in python
[], (), 0, "", None, False
all of these means that the value is False
Therefore:
newList = [i for i in myList if i] # this will create a new list which does not have any empty item
emptyList = [i for i in myList if not i] # this will create a new list which has ONLY empty items
or as you asked:
for i in myList:
if i:
# do whatever you want with your assigned values
else:
# do whatever you want with null values (i.e. [] or () or {} or None or False...)
and then you can do whatever you want with your new list :)
for sublist in mylist:
if sublist is None:
#what to do with None
continue
elif not sublist and isinstance(sublist, list):
#what to do if it's an empty list
continue
elif not isinstance(sublist, list):
#what to do if it's not a list
continue
#what to do if it's a list and not empty
Alternatively, you could leave out the 'continues' and put the general case in an else clause, only check for some of the possible circumstances, or nest the ifs.
Generally, if you knew you'd only get None or a container, just if not sublist: continue is adequate to ignore empty containers and None. To filter these values out of the list, do
mylist = [sublist for sublist in mylist if sublist]
Edit: You can't do this in the update function. You should pre-filter the list. Where you have
mylist = oldlist[:]
replace it with
mylist = [sublist for sublist in oldlist if sublist]
If the row name a, b, or whatever is there, but the rest is empty / None, then do
mylist = [sublist for sublist in oldlist if sublist[1]]
and this will filter on the truth value of the 2nd item intead of the first item / row title.
I will just do this:
for x in mylist:
if not x:
continue
#--> do what you want to do
but I have to say the first answer with comprehension list is more clean unless you need to do a complicated stuff inside the for statement.
How about this piece of code:
for x in mylist:
if x is None or x == [] or x == ():
continue
else:
do this